local skynet = require "skynet"
local cluster = require "skynet.cluster"
local filelog = require "filelog"
local base = require "base"
local timer = require "timer"
local timetool = require "timetool"
local redisdao = require "redisdao"
local configdao = require "configdao"
local tabletool = require "tabletool"
local filename = "tablelogic.lua"
local cardtool = require "ssscardtool"
local handcardstool = require "handcardstool"
local json = require "cjson"
json.encode_sparse_array(true,1,1)
require "pubenum"
require "sssenum"

local tablelogic = {
	server == nil
}

local function getdnnodetipconf()
	local dnnodeconf = nil
	local dnnodetipconf = nil
	local result, data = redisdao.query_data(".gmmqredis", "get", "dnnode_conf")
    if result and data then
        dnnodeconf = json.decode(data)
        dnnodetipconf = tabletool.deepcopy(dnnodeconf.tipconf)
    end
    if not dnnodetipconf then
        return nil
    else
    	return dnnodetipconf
    end
end

local function getjackoptconf()
	local dnnodeconf = nil
	local dnjackoptconf = nil
	local result, data = redisdao.query_data(".gmmqredis", "get", "dnnode_conf")
	if result and data then
		dnnodeconf = json.decode(data)
		dnjackoptconf = tabletool.deepcopy(dnnodeconf.jackoptconf)
	end
	if not dnjackoptconf then
		return nil
	else
		return dnjackoptconf
	end
end

local function check_cangetjack(card_type)
	local canget = false
	local jackoptconf = getjackoptconf()
	if not jackoptconf or not jackoptconf.getjackopt then return canget end
	for cardtype, get_per in pairs(jackoptconf.getjackopt) do
		if tonumber(cardtype) == card_type then canget = true break end
	end
	return canget
end

function tablelogic.init(service)
	if tablelogic.server == nil then
		tablelogic.server = service
	end
end

function tablelogic.resetdata()
	local server = tablelogic.server
	local table_data = server.table_data
	if table_data.cardspools ~= nil then table_data.cardspools = nil end
	table_data.banker_seat_index = 0
	table_data.one_start_time = 0
	table_data.one_end_time = 0
	table_data.cards_stack = nil
	table_data.tablerecords = nil
	table_data.conf.curr_round_code = "----"
	table_data.replaylogname = ""
	table_data.table_end_flag = false
	table_data.is_rematch = false
	table_data.deal_cards_temp = {}
	table_data.all_player_shootinfos = {}
	table_data.shoot_allplayer_infos = {}
	table_data.shoot_allplayer_rid = 0
	table_data.next_start_readytime = 0
end

function tablelogic.init_data(tableobj, conf, node_id)
	local service = tablelogic.server
	if conf == nil or node_id == nil then
		filelog.sys_error(filename .. "conf == nil or node_id == nil ", conf, node_id)
		return 
	end
	tableobj.conf = tabletool.deepcopy(conf)
	tableobj.baseTimes = conf.common_times
	local gamelogic = tablelogic.get_gamelogic()
	if gamelogic == nil then
		filelog.sys_error(filename .. "-----table_type-----error-------")
		return
	end
	tableobj.table_index = conf.table_index
	tableobj.svr_id = node_id
	local seatlogic = service:get_logicbyname("seatlogic")
	local seat
	local count = 1
	while count <= conf.max_player_num do
		seat = {
			index = 0,
			rid = 0,
			state = 0,
			gatenode_id = "",
			agent_address = -1,
			playerinfo = {
				rolename="",
				logo="",
				sex=0,
				ip="",
				adress_gps = 1,
				gps_addr = "",
				ip_address = "",
				diamond = 0,
				fangka = 0,
				coin = 0,
				intro = "",
				upvoted_num = 0,
				downvoted_num = 0,
				logoframe = 0,
			},
			is_tuoguan = 0,
			is_robot = false,		--是否是机器人
			is_mirror = false,		--是否是镜像(练习场陪练)
			will_action = 0,
			action_type = 0,
			timer_id = 0,			--定时器
			action_to_time = 0,		--操作超时时间
			cancel_timerid = -1,	 --解散牌桌定时器
			timeout_count = 0,		---玩家操作超时次数
			win = 0,				---记录玩家这局游戏的输赢
			score = 0,				----用于房卡场结算
			coin = 0,				----友豆(用于友豆场)
			diamond = 0,			----钻石(又叫元宝,用于元宝场)
    		ready_timer_id = -1, ----准备倒计时定时器
    		ready_to_time = 0,   ----准备到期时间
			cards = {},		     ----玩家手牌
			final_cards = nil,
			is_disconnected = 0, ----玩家是否断线
			add_times = 1,		 ----玩家加倍倍数
			balance_score = 0,	 ----最终结算分数
			is_force_quit = 0,	 ----玩家是否强退
			tuoguan_punish = 0, 
			holdvalue = 0, 		 ----玩家货币持有量
			dealnum = 0, 		 ----玩家中间结算量
			is_matching = false,
			balance_total = 0,	 ----自从进桌以来的总输赢
			continue_games = 0,
			is_delay_leave = false,
			special_card_type = 0,
			sorted_items = {},   ----理牌后的牌堆		
			deal_allwater = 0,
			deal_allwater_info = {}, ---和每个玩家结算的数据
			shoot_players_list = {}, ---打枪玩家的index 和 rid
			is_shoot_allplayers = false, ---是否全垒打
			deal_as_special		= 0,	---是否按照特殊牌型结算 默认为0
		}
		seatlogic.initseat(seat, count)
		table.insert( tableobj.seats, seat)
		count = count + 1
	end
	tableobj.gamelogic = {
		tableobj = nil,
		stateevent = {}
	}
	gamelogic.initstate(tableobj.gamelogic, tableobj)
	tableobj.is_can_kick = true
	if tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZUANSI then
		if tableobj.delete_table_timer_id == -1 then
			local noticemsg = {
				table_index = tableobj.conf.table_index,
				reason = "tableempty",
			}
			tableobj.delete_table_timer_id = timer.settimer(tableobj.conf.timeout*100, "delete_table", noticemsg)
		end
		---开启心跳检测
		service:check_table_alive()
		----开启部分钻石场陪练跑数据
		if tableobj.conf.is_train_diamond == 1 then
			local trainlogic = service:get_logicbyname("trainlogic")
			trainlogic.init_mirrors(tableobj.conf.table_index)
		end
	elseif  tableobj.conf.table_type == SSSTableType.TABLE_TYPE_COIN then
		if tableobj.delete_table_timer_id == -1 then
			local noticemsg = {
				table_index = tableobj.conf.table_index,
				reason = "tableempty",
			}
			tableobj.delete_table_timer_id = timer.settimer(tableobj.conf.timeout*100, "delete_table", noticemsg)
		end
		---开启心跳检测
		service:check_table_alive()
	elseif tableobj.conf.table_type == SSSTableType.TABLE_TYPE_TRAIN then
		local trainlogic = service:get_logicbyname("trainlogic")
		trainlogic.init_mirrors(tableobj.conf.table_index)
		---开启心跳检测
		service:check_table_alive()
	elseif tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
		if tableobj.delete_table_timer_id == -1 then
			local noticemsg = {
				table_index = tableobj.conf.table_index,
				reason = "tableempty",
			}
			tableobj.delete_table_timer_id = timer.settimer(tableobj.conf.retain_time*100, "delete_table", noticemsg)
		end
		---开启心跳检测
		service:check_table_alive()
	end
	if conf.circlecount then
		tableobj.circlecount = 0
	end
	filelog.sys_error("-----tablelogic.init_data-------")
	tableobj.state = SSSTableState.TABLE_STATE_GAME_START
	gamelogic.run(tableobj.gamelogic)
	return true
end

function tablelogic.get_gamelogic()
	local server = tablelogic.server
	local table_data = server.table_data
	local gamelogic = nil
	if table_data.conf.table_type == SSSTableType.TABLE_TYPE_ZUANSI then
		gamelogic = server:get_logicbyname("zsgamelogic")
	elseif table_data.conf.table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
		gamelogic = server:get_logicbyname("zjzsgamelogic")
	elseif table_data.conf.table_type == SSSTableType.TABLE_TYPE_FANGKA then
		gamelogic = server:get_logicbyname("fkgamelogic")
	elseif table_data.conf.table_type == SSSTableType.TABLE_TYPE_TRAIN then
		gamelogic = server:get_logicbyname("sygamelogic")
	elseif table_data.conf.table_type == SSSTableType.TABLE_TYPE_COIN then
		gamelogic = server:get_logicbyname("ggamelogic")
	end
	return gamelogic
end

function tablelogic.getallrids(table_data)
	local rids = {}
	if table_data.conf.table_type == SSSTableType.TABLE_TYPE_ZUANSI or table_data.conf.table_type == SSSTableType.TABLE_TYPE_FANGKA 
		or table_data.conf.table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
		for index, seatobj in ipairs(table_data.seats) do
			if seatobj.rid ~= 0 and seatobj.is_matching == false and seatobj.is_robot == false then table.insert(rids, seatobj.rid) end
		end
		for index, waitinfo in pairs(table_data.waits) do
			if waitinfo.rid ~= 0 and waitinfo.is_matching == false and waitinfo.is_robot == false then table.insert(rids, waitinfo.rid) end
		end
	elseif table_data.conf.table_type == SSSTableType.TABLE_TYPE_COIN then
		for index, seatobj in ipairs(table_data.seats) do
			if seatobj.rid ~= 0 and seatobj.is_matching == false and seatobj.is_robot == false then table.insert(rids, seatobj.rid) end
		end
		for index, waitinfo in pairs(table_data.waits) do
			if waitinfo.rid ~= 0 and waitinfo.is_matching == false and seatobj.is_robot == false then table.insert(rids, waitinfo.rid) end
		end
	end
	return rids
end

function tablelogic.copy_table_baseinfo(table_baseinfo)
	local table_data = tablelogic.server.table_data
	--[[
	//桌子的基本相关信息
	message table_baseinfo{
		optional int32 table_index = 1;
		optional string uuid = 2;				//桌子的唯一id，nodename_timenow_code，查看大战绩时也可以使用
		optional int32 code = 3;				//随机桌号,客户端也显示成房间号
		optional int32 state = 4;				//table 状态（准备， 玩牌）
		optional int32 create_rid = 5;			//创建者rid
		optional string create_rolename = 6;	//创建者姓名
		optional int32 create_time = 7;			//桌子的创建时间
		optional int32 max_player_num = 8;		//桌子支持玩家位置数（旁观的不算）2-5人
		optional int32 cur_player_num = 9;		//当前坐在位置上人数
		optional int32 curr_to_num = 10;			//游戏当前已经进行了的局数
		optional int32 retain_to_time = 11;		//桌子保留到的时间(linux时间擢)id
		optional int32 action_timeout = 12;		//玩家操作限时
		optional int32 action_timeout_count = 13; //玩家可操作超时次数	
		optional int32 table_type = 14;			//房间类型，其实就是桌子类型
		optional int32 sort_cards_time = 15;	//理牌时间
	}
	--]]
	table_baseinfo.table_index = table_data.conf.table_index
	table_baseinfo.uuid = table_data.conf.uuid
	table_baseinfo.code = table_data.conf.create_table_id
	table_baseinfo.state = table_data.state
	table_baseinfo.create_rid = table_data.conf.create_user_rid
	table_baseinfo.create_rolename = table_data.conf.create_user_rolename
	table_baseinfo.create_time = table_data.conf.create_time
	table_baseinfo.max_player_num = table_data.conf.max_player_num
	table_baseinfo.cur_player_num = table_data.conf.cur_player_num
	table_baseinfo.curr_to_num = table_data.curr_to_num
	table_baseinfo.retain_to_time = table_data.conf.retain_to_time
	table_baseinfo.action_timeout = table_data.conf.action_timeout
	table_baseinfo.action_timeout_count = table_data.conf.action_timeout_count
	table_baseinfo.table_type = table_data.conf.table_type
	table_baseinfo.sort_cards_time = table_data.conf.sort_cards_time
end

function tablelogic.copy_table_conf(table_conf)
	local table_data = tablelogic.server.table_data
	--[[
	//创建桌子，桌子的配置，返回桌子配置信息
	message table_conf {
		optional int32  table_type      	= 1;	//游戏桌类型： 1 系统钻石桌 2 自建钻石桌 3 自建房卡 4 练习桌 5 友豆场
		optional int32  shoot_times			= 2;	//打枪倍数
		optional int32	shoot_players		= 3;    //打枪玩家数达到数量后再翻倍
		optional int32	shoot_players_times = 4;    //翻倍数
		optional int32  have_joker			= 5;    //是否开启百变王牌(0, 1)
		optional int32  sort_cards_time     = 6;	//理牌时间
		//通用设置
		optional int32	max_player_num		= 7;	//桌子支持玩家位置数 5人
		//只有房卡场
		optional int32	retain_to_num		= 8;	//创建房间局数，只创建房卡需要
		optional int32  cost_type  			= 9;	//房卡花费模式：1 房主自负，2 AA
		optional int32  base_score      	= 10;	//基础分
		optional int32  max_score       	= 11;	//上限分
		//钻石场(数据库里就是钻石)
		optional int32	is_public			= 12;	//是否公开，列表里可以看见（1:公开，0：私密好友）
		optional int32	score_diamond		= 13;	//底注多少钻石，就是一分多少钻石
		optional int32	enter_diamond		= 14;	//进桌多少钻石（客户端计算其实是根据多少分来算的，用户不用随便填写
		optional int32	leave_diamond		= 15;	//离桌多少钻石（计算其实是根据多少分来算的）
		optional int32  tip					= 16;	//房间服务费
		optional string curr_round_code 	= 17;	//牌局唯一ID
	}
	]]
	table_conf.table_type = table_data.conf.table_type
	table_conf.shoot_times = table_data.conf.shoot_times
	table_conf.shoot_players = table_data.conf.shoot_players
	table_conf.shoot_players_times = table_data.conf.shoot_players_times
	table_conf.have_joker = table_data.conf.is_have_joker
	table_conf.sort_cards_time = table_data.conf.sort_cards_time
	table_conf.max_player_num = table_data.conf.max_player_num

	table_conf.retain_to_num = table_data.conf.retain_to_num
	table_conf.cost_type = table_data.conf.cost_type
	table_conf.base_score = table_data.conf.base_score
	table_conf.max_score = table_data.conf.max_score

	table_conf.is_public = table_data.conf.is_public
	table_conf.score_diamond = table_data.conf.score_diamond
	table_conf.enter_diamond = table_data.conf.enter_diamond
	table_conf.leave_diamond = table_data.conf.leave_diamond
	table_conf.tip = tablelogic.get_tip()
	table_conf.curr_round_code = table_data.conf.curr_round_code

end

function tablelogic.copy_seat_baseinfo(seat_baseinfo, seat)
	local server = tablelogic.server
	local table_data = tablelogic.server.table_data
	local roomseatlogic = server:get_logicbyname("seatlogic")
	--[[
	//座位基本信息，显示在牌桌上的
//座位基本信息，显示在牌桌上的
message seat_baseinfo {
	optional int32 rid 						= 1;
	optional int32 index 					= 2;
	optional int32 state 					= 3;
	optional int32 is_tuoguan 				= 4;		//是否托管（离线）， 1表示是 0表示否
	optional int32 score 					= 5;		//积分的时候可以为为负数
	optional int32 diamond 					= 6;		//打钻石场的时候，显示的钻石数量
	optional int32 coin 					= 7;		//友豆(友豆场显示友豆数量)
	optional int32 ready_to_time 			= 8;		//玩家跟牌倒数计时，到期时间戳
	optional int32 curr_score 				= 9;		// 当前局得分
	optional int32 total_score 				= 10;		// 总得分
    optional int32 is_sorted_cards 			= 11;		// 是否理牌(0, 1)
	optional int32 cards_num 				= 12;		// 手牌数量
	optional int32 action_type 				= 13;
	optional int32 deal_all_score			= 14;		// 总输赢水数
	optional int32 special_cards_type 		= 15;		// 特殊牌型
	repeated int32 hand_cards 				= 16;		// 亮牌牌值
	repeated cards_item sorted_cards_items 	= 17; 		// 理牌后的牌
	repeated int32 shoot_players 			= 18;		// 打枪的玩家
}
	]]
	seat_baseinfo.rid = seat.rid
	seat_baseinfo.index = seat.index
	seat_baseinfo.state = seat.state
	seat_baseinfo.is_tuoguan = seat.is_tuoguan
	seat_baseinfo.score = seat.score or 0
	seat_baseinfo.diamond = seat.diamond
	seat_baseinfo.coin = seat.coin or 0
	seat_baseinfo.ready_to_time = seat.ready_to_time
	seat_baseinfo.curr_score = seat.curr_score or 0
	seat_baseinfo.total_score = seat.total_score or 0
	if roomseatlogic.is_ingame(seat) then
		seat_baseinfo.cards_num = 13
	else
		seat_baseinfo.cards_num = #seat.cards
	end
	seat_baseinfo.action_type = seat.action_type
	seat_baseinfo.hand_cards = {}
	seat_baseinfo.sorted_cards_items = {}
	seat_baseinfo.shoot_players = {}
	seat_baseinfo.deal_all_score = 0
	seat_baseinfo.special_cards_type = 0
	seat_baseinfo.is_sorted_cards = -1
	if seat.state == SSSSeatState.SEAT_STATE_SORTCARDS_OVER then
		seat_baseinfo.deal_all_score = seat.deal_all_score
		if seat.special_card_type ~= 0 then
			if seat.deal_as_special == 1 then
				seat_baseinfo.special_cards_type = seat.special_card_type
			else
				seat_baseinfo.special_cards_type = 0
			end
		end
		seat_baseinfo.is_sorted_cards = 1
		for index, value in ipairs(seat.cards) do
			table.insert(seat_baseinfo.hand_cards, value)
		end
	end
end

function tablelogic.copy_seat_gameinfo(seat_gameinfo)
	local table_data = tablelogic.server.table_data
	--[[
		//座位上和游戏相关的信息
		message seat_gameinfo{
			optional int32 rid = 1;
			optional int32 curr_score = 2;			// 当前局得分
			optional int32 total_score = 3;			// 总得分
    		optional bool is_banker = 4;			// 是否是庄家
		}
	]]
	for index, seat in ipairs(table_data.seats) do
		local gameinfo = {
			rid = seat.rid,
			curr_score = seat.curr_score or 0,
			total_score = seat.total_score or 0,
			is_banker = seat.is_banker or false,
		}
		table.insert(seat_gameinfo, gameinfo)
	end 
end

function tablelogic.copy_seat_playerinfo(seat_playerinfo, seat)
	local table_data = tablelogic.server.table_data
	--[[
	//玩家个人信息
message seat_playerinfo {
	required int32 rid = 1;
	optional int32 index = 2;
	optional string role_name = 3;
	optional string logo = 4;
	optional int32 	sex = 5;
	optional int32	diamond = 6; 
	optional int32  fangka = 7;
	optional int32	coin = 8;
	optional string ip_address = 9; //玩家ip地址
	optional string intro = 10;	// 玩家简介
	optional int32  upvoted_num = 11; //玩家点赞数
	optional int32  downvoted_num = 12; // 玩家拉黑数
	optional string gps_addr	= 13; // 玩家位置信息
	optional int32  logoframe  	= 14;	//头像框id
}
	]]
	seat_playerinfo.rid = seat.rid
	seat_playerinfo.index = seat.index
	seat_playerinfo.role_name = seat.playerinfo.rolename
	seat_playerinfo.logo = seat.playerinfo.logo
	seat_playerinfo.sex = seat.playerinfo.sex
	seat_playerinfo.diamond = seat.playerinfo.diamond
	seat_playerinfo.fangka = seat.playerinfo.fangka
	seat_playerinfo.coin = seat.playerinfo.coin
	seat_playerinfo.ip_address = seat.playerinfo.ip_address
	seat_playerinfo.intro = seat.playerinfo.intro
	seat_playerinfo.upvoted_num = seat.playerinfo.upvoted_num
	seat_playerinfo.downvoted_num = seat.playerinfo.downvoted_num
	seat_playerinfo.gps_addr = seat.playerinfo.gps_addr
	seat_playerinfo.logoframe = seat.playerinfo.logoframe
end

function tablelogic.copy_table_game_info(game_info)
	local table_data = tablelogic.server.table_data
	--[[
	//牌局信息的汇总大集合，也是最重要的数据结构，
	message table_gameinfo {
		required table_baseinfo	table_baseinfo	= 1;
		required table_conf		table_conf		= 2;
		repeated seat_baseinfo	seat_baseinfo	= 3;
		repeated seat_playerinfo seat_playerinfo = 4;
	}
	]]
	local table_baseinfo = game_info.table_baseinfo
	tablelogic.copy_table_baseinfo(table_baseinfo)
	local table_conf = game_info.table_conf
	tablelogic.copy_table_conf(table_conf)
	local seat_baseinfos = game_info.seat_baseinfo
	local seat_playerinfos = game_info.seat_playerinfo
	for index, seat in ipairs(table_data.seats) do
		local seat_baseinfo = {}
		tablelogic.copy_seat_baseinfo(seat_baseinfo, seat)
		local seat_playerinfo = {}
		tablelogic.copy_seat_playerinfo(seat_playerinfo, seat)
		table.insert(seat_baseinfos, seat_baseinfo)
		table.insert(seat_playerinfos, seat_playerinfo)
	end
end

function tablelogic.copy_gameendinfo(gameendinfos)
	--[[
		//座位上每个玩家的结算信息
		message player_gameend {
    		optional int32 	rid 					= 1; 	//玩家rid
    		optional string role_name 				= 2; 	//玩家名字
    		optional int32 all_scores 				= 3; 	//当前玩家总积分(如果是自建钻石场就是钻石)
    		optional int32 get_scores 				= 4; 	//本局游戏获得积分
			optional int32 seat_index 				= 5; 	//座位号
			optional int32 special_cards_type 		= 6;	//特殊牌型
			optional int32 deal_all_score			= 7;	//总输赢水数
			optional int32 shoot_all_rid 			= 8;    //全垒打玩家rid(没有就是1)
			repeated int32 hand_cards 				= 9; 	//手牌
			repeated cards_item sorted_cards_items  = 10; 	//理牌后的牌
			repeated int32 shoot_players 			= 11;	//打枪的玩家
		}
		message cards_item{
			optional int32 card_slot_index 			= 1;		//道序列号(分头道(3张牌)，中道(5张牌)，尾道(5张牌))
			optional int32 card_type 				= 2; 		//牌型
			optional int32 deal_score 				= 3;		//道输赢
			repeated int32 cards      				= 4;        //牌数据
		}
	]]

	local table_data = tablelogic.server.table_data
	for index, seat in ipairs(table_data.seats) do
		if seat.rid ~= 0 and seat.state ~= SSSSeatState.SEAT_STATE_WAIT_NEXT_GAME then
			local gameend = {
				rid = seat.rid,
				role_name = seat.playerinfo.rolename,
				all_scores = seat.diamond,
				get_scores = seat.balance_score,
				seat_index = seat.index,
				special_cards_type = seat.special_card_type,
				deal_all_score = seat.deal_allwater,
				shoot_all_rid = 1,
				hand_cards = seat.cards,
				sorted_cards_items = {},
				shoot_players = {},
			}
			for slot_id, sort_item in ipairs(seat.sorted_items) do
				gameend.sorted_cards_items[sort_item.card_slot_index] = {
					card_slot_index = sort_item.card_slot_index,
					card_type 		= sort_item.card_type,
					deal_score 		= sort_item.deal_score,
					cards      		= sort_item.cards,
				}
			end
			for index, shoot_player in ipairs(seat.shoot_players_list) do
				table.insert(gameend.shoot_players, shoot_player.rid)
			end

			if seat.special_card_type ~= 0 then
				if seat.deal_as_special == 1 then
					gameend.special_cards_type = seat.special_card_type
				else
					gameend.special_cards_type = 0
				end
			end

			if table_data.shoot_allplayer_rid ~= 0 then
				gameend.shoot_all_rid = table_data.shoot_allplayer_rid
			end

			if table_data.conf.table_type == SSSTableType.TABLE_TYPE_TRAIN then
				gameend.all_scores = seat.train_score
			elseif table_data.conf.table_type == SSSTableType.TABLE_TYPE_FANGKA then
				gameend.all_scores = seat.score
			end
			table.insert(gameendinfos, gameend)
		end
	end
end

function tablelogic.copy_shootplayerinfos(shoot_playersinfo)
	--[[
	message shoot_playerinfo {
		optional int32 shoot_player_rid 			= 1;		//打枪玩家rid
		optional int32 shoot_player_index			= 2;		//打枪玩家index
		optional int32 shoot_player_win_water 		= 3;		//打枪玩家赢水数
		optional int32 be_shoot_player_rid 			= 4;		//被打枪玩家rid
		optional int32 be_shoot_player_index 		= 5;		//被打枪玩家index
		optional int32 be_shoot_player_lose_water 	= 6;		//被打枪玩家输水数
	}
	--]]
	local server = tablelogic.server
	local table_data = server.table_data
	filelog.sys_error("--------tablelogic.copy_shootplayerinfos-------", shoot_playersinfo, table_data.all_player_shootinfos)
	for index, info in ipairs(table_data.all_player_shootinfos) do
		local base_data = {
			shoot_player_rid 	= info.shoot_player_rid,
			shoot_player_index 	= info.shoot_player_index,
			shoot_player_win_water = info.shoot_player_win_water,
			be_shoot_player_rid = info.be_shoot_player_rid,
			be_shoot_player_index = info.be_shoot_player_index,
			be_shoot_player_lose_water = info.be_shoot_player_lose_water,
		}
		table.insert(shoot_playersinfo, base_data)
	end
end

function tablelogic.copy_shootallplayerinfos(shoot_allplayersinfo)
	local server = tablelogic.server
	local table_data = server.table_data
	filelog.sys_error("--------tablelogic.copy_shootallplayerinfos---------", table_data.shoot_allplayer_infos)
	for index, info in ipairs(table_data.shoot_allplayer_infos) do
		local base_data = {
			shoot_player_rid 	= info.shoot_player_rid,
			shoot_player_index 	= info.shoot_player_index,
			shoot_player_win_water = info.shoot_player_win_water,
			be_shoot_player_rid = info.be_shoot_player_rid,
			be_shoot_player_index = info.be_shoot_player_index,
			be_shoot_player_lose_water = info.be_shoot_player_lose_water,
		}
		table.insert(shoot_allplayersinfo, base_data)
	end
end

function tablelogic.copy_tablebalance(playergamerecordlist)
	local server = tablelogic.server
	local table_data = server.table_data
	if table_data.conf.table_type ~= SSSTableType.TABLE_TYPE_FANGKA then return end 
	if table_data.gamerecords == nil then return end
	for rid, record in pairs(table_data.gamerecords) do
		local base_record = {
			rid = record.rid,
			total_score = record.total_score,
			win_num = record.win_num,
			fail_num = record.fail_num,
			rolename = record.rolename,
			logo = record.logo,
		}
		table.insert(playergamerecordlist, base_record)
	end
end

function tablelogic.entertable(tableobj, rid, msgbody, roledata, seat)
	if seat == nil then
		local waitinfo = tableobj.waits[rid]
		if waitinfo == nil then
			tableobj.waits[rid] = {}
			waitinfo = tableobj.waits[rid]
			waitinfo.playerinfo = {}
			tableobj.waits[rid] = waitinfo
			tableobj.cur_watch_playernum = tableobj.cur_watch_playernum + 1			 
		end
		waitinfo.rid = rid
		waitinfo.gatesvr_id = "gatenode"
		waitinfo.is_mirror = false
		waitinfo.is_matching = false
		waitinfo.is_robot = false
		waitinfo.playerinfo.rolename = roledata.info.rolename
		waitinfo.playerinfo.logo = roledata.info.rolename
		waitinfo.playerinfo.sex = roledata.info.sex
		waitinfo.playerinfo.diamond = roledata.money.diamond
		waitinfo.playerinfo.coin = roledata.money.coin
		waitinfo.playerinfo.fangka = roledata.money.fangka
		waitinfo.playerinfo.intro = roledata.info.intro
		waitinfo.playerinfo.ip_address = roledata.ip_addr
		waitinfo.playerinfo.upvoted_num = roledata.info.upvoted_num
		waitinfo.playerinfo.downvoted_num = roledata.info.downvoted_num
		waitinfo.playerinfo.gps_addr = roledata.gps_addr
		waitinfo.playerinfo.logoframe = roledata.info.logoframe
		waitinfo.playerinfo.level = roledata.info.level
	end
end


function tablelogic.get_seat_by_rid(tableobj, rid)

	for index, seat in pairs(tableobj.seats) do
		if rid == seat.rid then
			return seat
		end
	end
	return nil
end

---判断当前桌子是否已经坐满
function tablelogic.is_full(tableobj)
	return (tableobj.conf.cur_player_num >= tableobj.conf.max_player_num)
end

function tablelogic.sitdowntable(tableobj, msgbody, seat, playerdata, rid)
	local server = tablelogic.server
	local playerinfo = playerdata.info
	local money = playerdata.money
	tableobj.waits[rid] = nil
	tableobj.cur_watch_playernum = tableobj.cur_watch_playernum - 1
	seat.rid = rid
	seat.gatesvr_id = "node"
	seat.agent_address = "-1"
	seat.is_matching = false
	seat.playerinfo.rolename = playerinfo.rolename
	seat.playerinfo.logo = playerinfo.logo
	seat.playerinfo.sex	= playerinfo.sex
	seat.playerinfo.diamond = money.diamond
	seat.playerinfo.coin = money.coin
	seat.playerinfo.fangka = money.fangka
	seat.playerinfo.ip_address = playerdata.ip_addr
	seat.playerinfo.intro = playerinfo.intro
	seat.playerinfo.upvoted_num = playerinfo.upvoted_num
	seat.playerinfo.downvoted_num = playerinfo.downvoted_num
	seat.playerinfo.logoframe = playerinfo.logoframe
	seat.playerinfo.level = playerinfo.level
	seat.playerinfo.gps_addr = playerdata.gps_addr
	seat.state = SSSSeatState.SEAT_STATE_WAIT_READY
	if tableobj.conf.table_type == SSSTableType.TABLE_TYPE_TRAIN then
		seat.train_score = 100000
		seat.diamond = 0
	elseif tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZUANSI then
		seat.diamond = money.diamond
	elseif tableobj.conf.table_type == SSSTableType.TABLE_TYPE_COIN then
		seat.coin = money.coin
	elseif tableobj.conf.table_type == SSSTableType.TABLE_TYPE_FANGKA then
		seat.score = 0
		seat.coin = money.coin
	elseif tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
		seat.diamond = money.diamond
	end
	seat.balance_total = 0
	seat.ready_to_time = timetool.get_time() + tableobj.conf.ready_timeout
	seat.is_disconnected = 0
	if tableobj.state ~= SSSTableState.TABLE_STATE_WAIT_PLAYER_SITDOWN and 
		tableobj.state ~= SSSTableState.TABLE_STATE_WAIT_ALL_READY then
		if tableobj.conf.table_type == SSSTableType.TABLE_TYPE_FANGKA and 
				(tableobj.state == SSSTableState.TABLE_STATE_START_GAME or tableobj.state == SSSTableState.TABLE_STATE_WAIT_START_GAME) then
		else
			seat.state = SSSSeatState.SEAT_STATE_WAIT_NEXT_GAME
		end
	end
	--[[
	//桌子有玩家坐下通知
	message sitdowntableN {
		required int32 rid = 1;
		required seat_baseinfo seat_info = 2;
		required seat_playerinfo seat_playerinfo = 3;
	}
	]]
	local noticemsg = {
		rid = seat.rid,
		seat_info = {},
		seat_playerinfo = {},
	}
	tablelogic.copy_seat_baseinfo(noticemsg.seat_info, seat)
	tablelogic.copy_seat_playerinfo(noticemsg.seat_playerinfo, seat)
	local sendrids = tablelogic.getallrids(tableobj)
	server:send_notice_to_players(sendrids, "sitdowntableN", noticemsg, nil, nil)
	if seat.is_tuoguan == SSSBOOL.TRUE then
		seat.is_tuoguan = SSSBOOL.FALSE
	end
	if seat.ready_timer_id > 0 then
		timer.cleartimer(seat.ready_timer_id)
		seat.ready_timer_id = -1
	end
	---filelog.sys_error("--------seat.state-------tableobj.state-----", tableobj.state, seat.state)
	if seat.state == SSSSeatState.SEAT_STATE_WAIT_READY then
		local outoftimermsg = {
			table_index = tableobj.conf.table_index,
			rid = seat.rid,
			seat_index = seat.index,
			playerdata = tabletool.deepcopy(playerdata),
			is_matching = seat.is_matching,
		}
		seat.ready_timer_id = timer.settimer(tableobj.conf.ready_timeout*100, "doready", outoftimermsg)
    	seat.ready_to_time = timetool.get_time() + tableobj.conf.ready_timeout
		local doreadyntcmsg = {
			rid = seat.rid,
			seat_index = seat.index,
			ready_to_time = timetool.get_time() + tableobj.conf.ready_timeout,
		}

		server:send_notice_to_players(sendrids, "doreadyN", doreadyntcmsg, nil, nil)
		filelog.sys_error("-------doreadyN------", timetool.get_time(), doreadyntcmsg)
	end
    if tableobj.state == SSSTableState.TABLE_STATE_WAIT_PLAYER_SITDOWN then
        tableobj.state = SSSTableState.TABLE_STATE_WAIT_ALL_READY
    end
end


function tablelogic.matchsitdowntable(tableobj, msgbody, seat, playerdata, rid)
	local server = tablelogic.server
	local playerinfo = playerdata.info
	local money = playerdata.money
	tableobj.waits[rid] = nil
	tableobj.cur_watch_playernum = tableobj.cur_watch_playernum - 1
	seat.rid = rid
	seat.gatesvr_id = "node"
	seat.agent_address = "-1"
	seat.is_matching = true
	seat.playerinfo.rolename = playerinfo.rolename
	seat.playerinfo.logo = playerinfo.logo
	seat.playerinfo.sex	= playerinfo.sex
	seat.playerinfo.diamond = money.diamond
	seat.playerinfo.coin = money.coin
	seat.playerinfo.fangka = money.fangka
	seat.playerinfo.ip_address = playerdata.ip_addr
	seat.playerinfo.intro = playerinfo.intro
	seat.playerinfo.upvoted_num = playerinfo.upvoted_num
	seat.playerinfo.downvoted_num = playerinfo.downvoted_num
	seat.playerinfo.gps_addr = playerdata.gps_addr
	seat.playerinfo.logoframe = playerinfo.logoframe
	seat.playerinfo.level = playerinfo.level
	seat.state = SSSSeatState.SEAT_STATE_WAIT_READY
	if tableobj.conf.table_type == SSSTableType.TABLE_TYPE_TRAIN then
		seat.train_score = 100000
		seat.diamond = 0
	elseif tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZUANSI then
		seat.diamond = money.diamond
	elseif tableobj.conf.table_type == SSSTableType.TABLE_TYPE_COIN then
		seat.coin = money.coin
	elseif tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
		seat.diamond = money.diamond
	end
	seat.balance_total = 0
	seat.ready_to_time = timetool.get_time() + tableobj.conf.ready_timeout
	seat.is_disconnected = 0
	if playerdata.is_robot == true then
		seat.is_robot = true
	end
	if tableobj.state ~= SSSTableState.TABLE_STATE_WAIT_PLAYER_SITDOWN and 
		tableobj.state ~= SSSTableState.TABLE_STATE_WAIT_ALL_READY then
		seat.state = SSSSeatState.SEAT_STATE_WAIT_NEXT_GAME
	end
	--[[
	//桌子有玩家坐下通知
	message sitdowntableN {
		required int32 rid = 1;
		required seat_baseinfo seat_info = 2;
		required seat_playerinfo seat_playerinfo = 3;
	}
	]]
	local noticemsg = {
		rid = seat.rid,
		seat_info = {},
		seat_playerinfo = {},
	}
	tablelogic.copy_seat_baseinfo(noticemsg.seat_info, seat)
	tablelogic.copy_seat_playerinfo(noticemsg.seat_playerinfo, seat)
	local sendrids = tablelogic.getallrids(tableobj)
	server:send_notice_to_players(sendrids, "sitdowntableN", noticemsg, nil, nil)
	if seat.is_tuoguan == SSSBOOL.TRUE then
		seat.is_tuoguan = SSSBOOL.FALSE
	end
	if seat.ready_timer_id > 0 then
		timer.cleartimer(seat.ready_timer_id)
		seat.ready_timer_id = -1
	end
	if seat.state == SSSSeatState.SEAT_STATE_WAIT_READY then
		local outoftimermsg = {
			table_index = tableobj.conf.table_index,
			rid = seat.rid,
			seat_index = seat.index,
			playerdata = tabletool.deepcopy(playerdata),
			---is_matching = seat.is_matching,
		}
		local ready_timeout = tableobj.conf.ready_timeout
		filelog.sys_error("--------ready_timeout-------", ready_timeout)
		seat.ready_timer_id = timer.settimer(ready_timeout * 100, "doready", outoftimermsg)
    	seat.ready_to_time = timetool.get_time() + tableobj.conf.ready_timeout
		local doreadyntcmsg = {
			rid = seat.rid,
			seat_index = seat.index,
			ready_to_time = timetool.get_time() + tableobj.conf.ready_timeout,
		}
		---server:send_notice_to_players(sendrids, "doreadyN", doreadyntcmsg, nil, nil)
	end
    if tableobj.state == SSSTableState.TABLE_STATE_WAIT_PLAYER_SITDOWN then
        tableobj.state = SSSTableState.TABLE_STATE_WAIT_ALL_READY
    end
end

function tablelogic.get_emptyseat_by_index(tableobj, index)
	local server = tablelogic.server
	local roomseatlogic = server:get_logicbyname("seatlogic")
	if index == nil or index <= 0 or index > tableobj.conf.max_player_num then
		for index, seat in pairs(tableobj.seats) do
			if roomseatlogic.is_empty(seat) then
				return seat
			end
		end
	else
		local seat = tableobj.seats[index]
		if roomseatlogic.is_empty(seat) then
			return seat
		end
	end
	return nil
end

function tablelogic.check_has_enough_diamond(tableobj)
	local server = tablelogic.server
	for index, seat in ipairs(tableobj.seats) do
		if seat.rid ~= 0 and seat.state == SSSSeatState.SEAT_STATE_WAIT_START then
			if seat.diamond <= 0 or seat.diamond < tablelogic.get_tip() then
				tablelogic.passive_standuptable(tableobj, nil, seat, SSSEStandupReason.STANDUP_REASON_READYTIMEOUT_STANDUP)
			end
		end
	end
end

function tablelogic.check_has_enough_coin()
	local server = tablelogic.server
	local table_data = server.table_data
	for index, seat in ipairs(table_data.seats) do
		if seat.rid ~= 0 and seat.state == SSSSeatState.SEAT_STATE_WAIT_START then
			if seat.coin <= 0 or seat.coin < tablelogic.get_tip() then
				tablelogic.passive_standuptable(tableobj, nil, seat, SSSEStandupReason.STANDUP_REASON_READYTIMEOUT_STANDUP)
			end
		end
	end
end

function tablelogic.check_all_ready(tableobj)
	local allready = true
	local ready_num = 0 
	local is_one_leave = false
	for index, seat in ipairs(tableobj.seats) do
		if seat.rid ~= 0 and seat.state ~= SSSSeatState.SEAT_STATE_WAIT_START 
			and seat.state ~= SSSSeatState.SEAT_STATE_NO_PLAYER then
			allready = false
		end
		if seat.rid ~= 0 and seat.state == SSSSeatState.SEAT_STATE_WAIT_START then
			ready_num = ready_num + 1
		end
		if seat.rid == 0 then is_one_leave = true end
	end
	return allready, ready_num, is_one_leave
end

function tablelogic.has_real_player()
	local table_data = tablelogic.server.table_data
	local has_real = false
	for index, seatobj in ipairs(table_data.seats) do
		if seatobj.rid ~= 0 and seatobj.is_mirror == false then
			has_real = true
			break
		end
	end
	for index, waitinfo in pairs(table_data.waits) do
		if waitinfo.rid ~= 0 and waitinfo.is_mirror == false then
			has_real = true
			break
		end
	end
	return has_real
end

function tablelogic.gameready(tableobj, msgbody, seat, roledata)
	local server = tablelogic.server
	if tableobj.state ~= SSSTableState.TABLE_STATE_WAIT_ALL_READY then
		if tableobj.conf.table_type == SSSTableType.TABLE_TYPE_FANGKA and 
			(tableobj.state == SSSTableState.TABLE_STATE_START_GAME or tableobj.state == SSSTableState.TABLE_STATE_WAIT_START_GAME) then
		else return end
	end
	for index, playerseat in ipairs(tableobj.seats) do
        if playerseat.rid > 0 and playerseat.playerinfo and playerseat.playerinfo.level == 0 then
            local status, ridmap = skynet.pcall(skynet.call, ".router", "lua", "get_role_data", nil, playerseat.rid)
            if status == true and ridmap and next(ridmap) ~= nil then
                if not ridmap.table_index or ridmap.table_index ~= tableobj.conf.table_index then
                    tablelogic.passive_standuptable(tableobj, nil, playerseat, SSSEStandupReason.STANDUP_REASON_TABLE_CHUANZHUO)
                end
            else
                tablelogic.passive_standuptable(tableobj, nil, playerseat, SSSEStandupReason.STANDUP_REASON_TABLE_CHUANZHUO)
            end
        end
    end

	local noticemsg = {
		rid = seat.rid,
		seat_index = seat.index,
		is_ready = 0,
		table_state = 0,
	}
	if seat.state == SSSSeatState.SEAT_STATE_WAIT_START then noticemsg.is_ready = 1 end
	if tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZUANSI or tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
		seat.diamond = roledata.money.diamond
		seat.playerinfo.diamond = roledata.money.diamond
		tablelogic.check_has_enough_diamond(tableobj)
	elseif tableobj.conf.table_type == SSSTableType.TABLE_TYPE_COIN then
		seat.coin = roledata.money.coin
		seat.playerinfo.coin = roledata.money.coin
		tablelogic.check_has_enough_coin()
	end
	local is_allready, ready_num, is_one_leave = tablelogic.check_all_ready(tableobj)
	local readynum = 0
	for k, v in ipairs(tableobj.seats) do
		if v.rid ~= 0 and v.state == SSSSeatState.SEAT_STATE_WAIT_START then
			readynum = readynum + 1
		end
	end
	local start_player_num = tableobj.conf.start_player_num
	---filelog.sys_error("------start_player_num-----", start_player_num)
	if readynum > start_player_num - 1 and is_allready == true and tableobj.state == SSSTableState.TABLE_STATE_WAIT_ALL_READY then
		if tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZUANSI or tableobj.conf.table_type == SSSTableType.TABLE_TYPE_COIN 
			or tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
			tableobj.is_can_kick = false
			tableobj.state = SSSTableState.TABLE_STATE_ONE_GAME_START
			noticemsg.table_state = tableobj.state
			local sendrids = tablelogic.getallrids(tableobj)
			server:send_notice_to_players(sendrids, "gamereadyN", noticemsg, nil, nil)
		elseif tableobj.conf.table_type == SSSTableType.TABLE_TYPE_FANGKA then
			---房卡场玩家准备完毕,等待房主开始游戏
			if tableobj.curr_to_num == 0 then
				tableobj.state = SSSTableState.TABLE_STATE_START_GAME
			else
				tableobj.state = SSSTableState.TABLE_STATE_ONE_GAME_START
			end
			tableobj.is_can_kick = false
			noticemsg.table_state = tableobj.state
			local sendrids = tablelogic.getallrids(tableobj)
			server:send_notice_to_players(sendrids, "gamereadyN", noticemsg, nil, nil)
		end
		local gamelogic = tablelogic.get_gamelogic()
		gamelogic.run(tableobj.gamelogic)
	elseif readynum <= start_player_num - 1 and is_allready == true then
		if tableobj.conf.table_type == SSSTableType.TABLE_TYPE_TRAIN then
			if tableobj.timer_id > 0 then
				timer.cleartimer(tableobj.timer_id)
				tableobj.timer_id = -1
			end
			local noticemsg = {
        			table_index = tableobj.conf.table_index,
        			neednum = 1,
    			}
			tableobj.timer_id = timer.settimer(1*100, "train_add_mirror", noticemsg)
			noticemsg.table_state = tableobj.state
			local sendrids = tablelogic.getallrids(tableobj)
			server:send_notice_to_players(sendrids, "gamereadyN", noticemsg, nil, nil)
		elseif tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZUANSI or tableobj.conf.table_type == SSSTableType.TABLE_TYPE_COIN 
			or tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
			if tableobj.conf.match_type ~= 0 then
				noticemsg.table_state = tableobj.state
				local sendrids = tablelogic.getallrids(tableobj)
				server:send_notice_to_players(sendrids, "gamereadyN", noticemsg, nil, nil)
				if tableobj.is_rematch == false then
					is_allready, ready_num, is_one_leave = tablelogic.check_all_ready(tableobj)
					if is_one_leave == true then
						if is_allready == true and ready_num == 1 then
							tableobj.is_rematch = true
							tablelogic.restart_matchtable(tableobj, 0) --匹配场，将座位上玩家，加入匹配队列
							tableobj.is_rematch = false
						end
					end
				end
			else
				noticemsg.table_state = tableobj.state
				local sendrids = tablelogic.getallrids(tableobj)
				server:send_notice_to_players(sendrids, "gamereadyN", noticemsg, nil, nil)
			end
		elseif tableobj.conf.table_type == SSSTableType.TABLE_TYPE_FANGKA then
			noticemsg.table_state = tableobj.state
			local sendrids = tablelogic.getallrids(tableobj)
			server:send_notice_to_players(sendrids, "gamereadyN", noticemsg, nil, nil)
		end
	else
		noticemsg.table_state = tableobj.state
		local sendrids = tablelogic.getallrids(tableobj)
		server:send_notice_to_players(sendrids, "gamereadyN", noticemsg, nil, nil)
	end
end

function tablelogic.waitdoaction(tableobj, msgbody, seat, roledata)
	--[[
		//通知玩家操作结果
		message doactionN {
			optional int32 rid = 1;
			optional int32 seat_index = 2;
			optional int32 action_type = 3;
		}
	]]
	local server = tablelogic.server
	local rids = tablelogic.getallrids(tableobj)
	if seat.timer_id > 0 then
		timer.cleartimer(seat.timer_id)
		seat.timer_id = -1
	end

	if seat.state == SSSSeatState.SEAT_STATE_SORTCARDS_OVER then
		local doactionnotice = {
			rid = seat.rid,
			seat_index = seat.index,
			action_type = seat.action_type,
		}
		server:send_notice_to_players(rids, "doactionN", doactionnotice, nil, nil)
		filelog.sys_error("------------tablelogic.waitdoaction-----------", tableobj.state)
		----判断所有玩家是否都已经理牌完成
		local all_sort_over = tablelogic.check_players_sortover(tableobj)
		filelog.sys_error("------all_sort_over--------", all_sort_over)
		if all_sort_over == true and tableobj.state == SSSTableState.TABLE_STATE_WAIT_DEAL_ALL_CARDS_END then
			----玩家都理牌完成,游戏结算
			tableobj.state = SSSTableState.TABLE_STATE_SORT_CARDS
			local roomgamelogic = tablelogic.get_gamelogic()
			roomgamelogic.run(tableobj.gamelogic)
		end
	end
end

function tablelogic.check_players_qiangzhuang(tableobj)
	local all_bank = true
	for index, seat in ipairs(tableobj.seats) do
		if seat.rid ~= 0 and seat.state == SSSSeatState.SEAT_STATE_QIANGZHUANG then
			all_bank = false
			break
		end
	end
	return all_bank
end

function tablelogic.set_table_banker(tableobj)
	local server = tablelogic.server
	if tableobj.banker_seat_index ~= 0 then return end
	local temp = {
		highest_times = 0,
		indexandrids = {},
	}
	local roomseatlogic = server:get_logicbyname("seatlogic")
	for index, seat in ipairs(tableobj.seats) do
		if roomseatlogic.is_ingame(seat) and seat.action_type == DNActionType.ACTION_QIANGZHUANG then
			if seat.qiangzhuang_times > temp.highest_times then
				temp.highest_times = seat.qiangzhuang_times
				temp.indexandrids = {}
				local indexandrid = {index = seat.index, rid = seat.rid}
				table.insert(temp.indexandrids, indexandrid)
			elseif seat.qiangzhuang_times == temp.highest_times and seat.qiangzhuang_times > 0 then
				local indexandrid = {index = seat.index, rid = seat.rid}
				table.insert(temp.indexandrids, indexandrid)
			end
		end 
	end
	if temp.highest_times > 0 and #temp.indexandrids > 0 then
		if #temp.indexandrids == 1 then
			tableobj.banker_seat_index = temp.indexandrids[1].index
			tableobj.banker_xiazhu_times = temp.highest_times
		elseif #temp.indexandrids > 1 then
			local randoms = base.get_random(1, #temp.indexandrids)
			tableobj.banker_seat_index = temp.indexandrids[randoms].index
			tableobj.banker_xiazhu_times = temp.highest_times
		end
	elseif temp.highest_times == 0 then
		temp.highest_times = 1
		for index, seat in ipairs(tableobj.seats) do
			if roomseatlogic.is_ingame(seat) then
				local indexandrid = { index = seat.index, rid = seat.rid }
				table.insert(temp.indexandrids, indexandrid)
			end
		end
		local randoms = base.get_random(1, #temp.indexandrids)
		tableobj.banker_seat_index = temp.indexandrids[randoms].index
		tableobj.banker_xiazhu_times = temp.highest_times
	end
	for index, seat in ipairs(tableobj.seats) do
		if seat.index == tableobj.banker_seat_index then
			seat.iszj = DNPlayerIDType.DN_PLAYER_ID_BANKER
		else 
			seat.iszj = DNPlayerIDType.DN_PLAYER_ID_NOT_BANKER
		end
	end
	---把设置庄家的消息广播出来
	local zhuangseat = tableobj.seats[tableobj.banker_seat_index]
	if zhuangseat.qiangzhuang_times == 0 then
		zhuangseat.qiangzhuang_times = tableobj.banker_xiazhu_times
	end
	--[[
	//通知客户端哪个座位玩家是庄家
	message noticebankerN {
		optional int32 rid = 1;
		optional int32 seat_index = 2;
		optional int32 choice_times = 3;
		repeated int32 banker_indexs = 4;
	}
	]]
	local noticemsg = {
		rid = zhuangseat.rid,
		seat_index = zhuangseat.index,
		choice_times = zhuangseat.qiangzhuang_times,
		banker_indexs = {}
	}
	for key, ridandindex in ipairs(temp.indexandrids) do
		table.insert(noticemsg.banker_indexs, ridandindex.index)
	end
	local rids = tablelogic.getallrids(tableobj)
	server:send_notice_to_players(rids, "noticebankerN", noticemsg, nil, nil)
	local actioninfos = tableobj.tablerecords.actions
	local acobj = { rid = zhuangseat.rid, index = zhuangseat.index, action_type = DNActionType.ACTION_SET_BANKER, banker_times = zhuangseat.qiangzhuang_times}
	table.insert(actioninfos, acobj)
	local replaywrite = server:get_logicbyname("replaywrite")
	replaywrite.write_banker_info()
end

function tablelogic.check_players_xiazhu(tableobj)
	local all_xiazhu = true
	for index, seat in ipairs(tableobj.seats) do
		if seat.rid ~= 0 and seat.state == SSSSeatState.SEAT_STATE_XIAZHU then
			all_xiazhu = false
		end
	end
	return all_xiazhu
end

function tablelogic.check_players_sortover(tableobj)
	local all_sortover = true 
	for index, seat in ipairs(tableobj.seats) do
		if seat.rid ~= 0 and seat.state == SSSSeatState.SEAT_STATE_SORTCARDS then
			all_sortover = false
			break
		end
	end
	return all_sortover
end

function tablelogic.check_player_kaipai(tableobj)
	local all_kaipai = true
	for index, seat in ipairs(tableobj.seats) do
		if seat.rid ~= 0 and seat.state == SSSSeatState.SEAT_STATE_KAIPAI then
			all_kaipai = false
		end
	end
	return all_kaipai
end

function tablelogic.set_player_cardstype(seat)
	local server = tablelogic.server
	local table_data = server.table_data
	cardtool.analysis_card_type(seat, seat.cards, table_data.conf.is_open_flush)
end

local function is_hasindex(balance_indexs, index)
	local is_has = false
	if not balance_indexs or #balance_indexs <= 0 then
		return is_has
	end
	for k, value in ipairs(balance_indexs) do
		if value == index and index ~= 0 then
			is_has = true
		end
	end
	return is_has
end

function tablelogic.balance_protect(table_type, balance_indexs)
	local server = tablelogic.server
	local table_data = server.table_data
	local seatlogic = server:get_logicbyname("seatlogic")
	local zhuang_get = 0
	local zhuang_lost = 0
	local zhuang_seat = table_data.seats[table_data.banker_seat_index]
	if zhuang_seat == nil or #balance_indexs <= 1 then return end
	if table_type == SSSTableType.TABLE_TYPE_ZUANSI or table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
		zhuang_seat.holdvalue = zhuang_seat.diamond
	elseif table_type == SSSTableType.TABLE_TYPE_COIN then
		zhuang_seat.holdvalue = zhuang_seat.coin
	end
	local temp_balance = {}
	local total_ba = {
		win_limit = 0,
		lose_limit = 0,
		will_win_limit = 0,
		will_lost_limit = 0
	}
	for index, seat in ipairs(table_data.seats) do
		if seatlogic.is_ingame(seat) and is_hasindex(balance_indexs, seat.index) then
			if temp_balance[index] == nil then temp_balance[index] = {} end
			temp_balance[index].rid = seat.rid
			if table_type == SSSTableType.TABLE_TYPE_ZUANSI or table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
				temp_balance[index].limit = seat.diamond
			elseif table_type == SSSTableType.TABLE_TYPE_COIN then
				temp_balance[index].limit = seat.coin
			end
			temp_balance[index].unlimit_ban = seat.balance_score
			temp_balance[index].will_ba = 0
			if temp_balance[index].unlimit_ban > 0 then
				if temp_balance[index].limit >= temp_balance[index].unlimit_ban then
					total_ba.will_win_limit = total_ba.will_win_limit + temp_balance[index].unlimit_ban
					temp_balance[index].will_ba = temp_balance[index].unlimit_ban
				else
					total_ba.will_win_limit = total_ba.will_win_limit + temp_balance[index].limit
					temp_balance[index].will_ba = temp_balance[index].limit
				end
			end
			temp_balance[index].real_ba = 0
			if seat.balance_score > 0 then
				if table_type == SSSTableType.TABLE_TYPE_ZUANSI or table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
					total_ba.win_limit = total_ba.win_limit + seat.diamond
				elseif table_type == SSSTableType.TABLE_TYPE_COIN then
					total_ba.win_limit = total_ba.win_limit + seat.coin
				end
			elseif seat.balance_score < 0 then
				total_ba.lose_limit = total_ba.lose_limit + seat.balance_score
			end
		end
	end
	for index, temp in pairs(temp_balance) do
		if temp.will_ba == 0 then
			if math.abs(total_ba.lose_limit) > total_ba.will_win_limit then
				temp.will_ba =  - math.floor(temp.unlimit_ban * (total_ba.will_win_limit / total_ba.lose_limit))
			else
				temp.will_ba = temp.unlimit_ban
			end
			if math.abs(temp.will_ba) >= temp.limit then
				temp.real_ba = - temp.limit
			else
				temp.real_ba = temp.will_ba
			end
			if temp.real_ba < 0 then
				total_ba.will_lost_limit = total_ba.will_lost_limit + temp.real_ba
			end
		end
	end
	local win_all = 0
	local lose_all = 0
	for index, temp in pairs(temp_balance) do
		if temp.will_ba >= 0 then
			temp.real_ba = math.floor(math.abs(total_ba.will_lost_limit) * temp.will_ba / total_ba.will_win_limit)
		end
		if temp.real_ba >= 0 then
			win_all = win_all + temp.real_ba
		else
			lose_all = lose_all + temp.real_ba
		end
	end
	-- filelog.sys_error("-------xxxxxxxxxxx----", temp_balance, "----total----", total_ba)
	-- filelog.sys_error("--------win_all------",win_all, lose_all)
	if math.abs(win_all) >= math.abs(lose_all) then
		local dif = math.abs(win_all) - math.abs(lose_all)
		if dif > 0 then
			for index, temp in pairs(temp_balance) do
				if temp.real_ba < 0 and dif > 0 then
					if math.abs(temp.real_ba) + dif <= math.abs(temp.unlimit_ban) and math.abs(temp.real_ba) + dif <= math.abs(temp.limit) then
						temp.real_ba = temp.real_ba - dif
						dif = 0
					elseif math.abs(temp.real_ba) + math.floor(dif/2) <= math.abs(temp.unlimit_ban) and math.abs(temp.real_ba) + math.floor(dif/2) <= math.abs(temp.limit) then
						temp.real_ba = temp.real_ba - math.floor(dif/2)
						dif = dif - math.floor(dif/2)
					else
						local diflimit = math.abs(temp.will_ba) - math.abs(temp.real_ba)
						if diflimit >=0 then
							if diflimit <= dif then
								temp.real_ba = temp.real_ba - diflimit
								dif = dif - diflimit
							else
								temp.real_ba = temp.real_ba - dif
								dif = 0
							end
						end
					end
				end 
			end
		end
	else
		local dif = math.abs(lose_all) - math.abs(win_all) 
		if dif > 0 then
			for index, temp in pairs(temp_balance) do
				if temp.real_ba > 0 and dif > 0 then
					if math.abs(temp.real_ba) + dif <= math.abs(temp.unlimit_ban) and  math.abs(temp.real_ba) + dif <= math.abs(temp.limit) then
						temp.real_ba = temp.real_ba + dif
						dif = 0
					elseif math.abs(temp.real_ba) + math.floor(dif/2) <= math.abs(temp.unlimit_ban) and math.abs(temp.real_ba) + math.floor(dif/2) <= math.abs(temp.limit) then
						temp.real_ba = temp.real_ba + math.floor(dif/2)
						dif = dif - math.floor(dif/2)
					else
						local diflimit = math.abs(temp.will_ba) - math.abs(temp.real_ba)
						if diflimit >= 0 then
							if diflimit <= dif then
								temp.real_ba = temp.real_ba + diflimit
								dif = dif - diflimit
							else
								temp.real_ba = temp.real_ba + dif
								dif = 0
							end
						end
					end
				end 
			end
		end
	end
	for index, seat in ipairs(table_data.seats) do
		if seatlogic.is_ingame(seat) and is_hasindex(balance_indexs, seat.index) and seat.index ~= table_data.banker_seat_index then
			if table_type == SSSTableType.TABLE_TYPE_ZUANSI or table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
				seat.holdvalue = seat.diamond
				if seat.balance_score < 0 then
					if seat.balance_score + seat.diamond < 0 then 
						seat.balance_score = 0 - seat.diamond
					end
					zhuang_get = zhuang_get - seat.balance_score
				elseif seat.balance_score >= 0 then
					zhuang_lost = zhuang_lost + seat.balance_score
				end
			elseif table_type == SSSTableType.TABLE_TYPE_COIN then
				seat.holdvalue = seat.coin
				if seat.balance_score < 0 then
					if seat.balance_score + seat.coin < 0 then
						seat.balance_score = 0 - seat.coin
					end
					zhuang_get = zhuang_get - seat.balance_score
				elseif seat.balance_score >= 0 then
					zhuang_lost = zhuang_lost + seat.balance_score
				end
			end
		end
	end

	if table_type == SSSTableType.TABLE_TYPE_ZUANSI or table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
		if zhuang_get + zhuang_seat.diamond >= zhuang_lost then
			zhuang_seat.balance_score = zhuang_get - zhuang_lost
		else
			local real_lost = 0
			local add_xishu = (zhuang_get + zhuang_seat.diamond) / zhuang_lost
			for index, seat in ipairs(table_data.seats) do
				if seatlogic.is_ingame(seat) and seat.index ~= table_data.banker_seat_index then
					if seat.balance_score > 0 then
						real_lost = real_lost + math.floor(seat.balance_score * add_xishu)
						seat.balance_score = math.floor(seat.balance_score * add_xishu)
					end
				end
			end
			zhuang_seat.balance_score = 0 - zhuang_seat.diamond
		end
	elseif table_type == SSSTableType.TABLE_TYPE_COIN then
		if zhuang_get + zhuang_seat.coin >= zhuang_lost then
			zhuang_seat.balance_score = zhuang_get - zhuang_lost
		else
			local real_lost = 0
			local add_xishu = (zhuang_get + zhuang_seat.coin) / zhuang_lost
			for index, seat in ipairs(table_data.seats) do
				if seatlogic.is_ingame(seat) and seat.index ~= table_data.banker_seat_index then
					if seat.balance_score > 0 then
						real_lost = real_lost + math.floor(seat.balance_score * add_xishu)
						seat.balance_score = math.floor(seat.balance_score * add_xishu)
					end
				end
			end
			zhuang_seat.balance_score = 0 - zhuang_seat.coin
		end
	end
	---filelog.sys_error("+++++xxxxxxxxxxx+++++++", temp_balance)
	win_all = 0
	lose_all = 0
	for index, temp in pairs(temp_balance) do
		if temp.real_ba >= 0 then
			win_all = win_all + temp.real_ba
		else
			lose_all = lose_all + temp.real_ba
		end
	end
	if win_all ~= 0 and lose_all ~= 0 and win_all + lose_all ~= 0 then
		filelog.sys_error("---------没平账--------", temp_balance, "----uuid------", table_data.conf.uuid)
	end
	for index, seat in ipairs(table_data.seats) do
		if seatlogic.is_ingame(seat) then
			if temp_balance[index] and temp_balance[index].real_ba then
				if table_type == SSSTableType.TABLE_TYPE_ZUANSI or table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
					seat.balance_score = temp_balance[index].real_ba
				elseif table_type == SSSTableType.TABLE_TYPE_COIN then
					seat.balance_score = temp_balance[index].real_ba
				end
			end
		end
	end
	return temp_balance
end

local function write_table_log(comment, balance_pro_info)
	local server = tablelogic.server
	local table_data = server.table_data
	local records = table_data.tablerecords
	local tablelogic = server:get_logicbyname("tablelogic")
	local seatlogic = server:get_logicbyname("seatlogic")
	local ridstring = ""
	local handcards = {}
	local diamondinfo = {}
	local balanceinfo = {}
	local tmpdiamond = records.tmpdiamond
	for index,seat in ipairs(table_data.seats) do
		if  seatlogic.is_ingame(seat) then
			if ridstring == "" then
				ridstring = ridstring .. tostring(seat.rid)
			else
				ridstring = ridstring .. "_" .. tostring(seat.rid)
			end
			handcards[seat.rid] = tabletool.deepcopy(seat.cards)
			if tmpdiamond[seat.rid] then
				table.insert(diamondinfo, {
					rolename = tmpdiamond[seat.rid].rolename,
					value = tmpdiamond[seat.rid].value,
				})
				if balanceinfo[seat.rid] == nil then
					balanceinfo[seat.rid] = {}
				end
				balanceinfo[seat.rid].winvalue = tmpdiamond[seat.rid].value
				balanceinfo[seat.rid].gamestar_diamond = tmpdiamond[seat.rid].beginvalue
				balanceinfo[seat.rid].gameend_diamond = tmpdiamond[seat.rid].endvalue
			end
		end
	end
	local logname = tostring(table_data.conf.uuid) .. "_" ..tostring(table_data.one_start_time) .. "_" .. tostring(table_data.one_end_time) .. "_" .. ridstring
	local logstr = ''
		.. comment.table_uuid .. '\n'
		.. table_data.conf.table_type .. '\n'
		.. json.encode(records.tips) .. '\n'
		.. json.encode(table_data.conf) .. '\n'
		.. table_data.one_start_time .. '\n'
		.. table_data.one_end_time .. '\n'
		.. json.encode(balanceinfo) .. '\n'
		.. comment.table_tradeid .. '\n'
		.. json.encode(diamondinfo) .. '\n'
		.. json.encode(records.addinfos) .. '\n'				-- 结算算番情况
	if balance_pro_info ~= nil then
		logstr = logstr .. "\n" .. json.encode(balance_pro_info) .. "\n"
	end
	---skynet.call(".tablerecordlog", "lua", "write", logname, logstr)
end

----计算玩家输赢多少水
function tablelogic.balance_water(tableobj)
	local server = tablelogic.server
	local table_data = server.table_data
	local seatlogic = server:get_logicbyname("seatlogic")
	----通比

	for index, seat in ipairs(table_data.seats) do
		if seat.rid ~= 0 and seat.state == SSSSeatState.SEAT_STATE_SORTCARDS_OVER then
			----和自己以外的其他玩家结算输赢水数目 water_nums
			seatlogic.deal_water_withallplayer(seat)
		end
	end

	---检查是否是打全垒
	tablelogic.check_player_shootall()

	for index, seat in ipairs(table_data.seats) do
		seatlogic.deal_seatallwaternum(seat)
		filelog.sys_error("----------index, deal_allwater-----", index, seat.rid, seat.deal_allwater)
	end
	tablelogic.check_all_waternum_equal()
end
---检查是否是全垒打
function tablelogic.check_player_shootall()
	local server = tablelogic.server
	local table_data = server.table_data
	local shoot_allplayer_times = table_data.conf.shoot_players_times
	if table_data.conf.cur_player_num < table_data.conf.max_player_num then 
		filelog.sys_error("--------tablelogic.check_player_shootall-----not enough player num ----", shoot_allplayer_times)
		return
	end
	for index, seat in ipairs(table_data.seats) do
		if seat.rid ~= 0 and seat.state == SSSSeatState.SEAT_STATE_SORTCARDS_OVER then
			local shoot_player_num = #seat.shoot_players_list
			if shoot_player_num + 1 == table_data.conf.max_player_num then
				---全垒打
				seat.is_shoot_allplayers = true
				table_data.shoot_allplayer_rid = seat.rid
				for otherrid, water_info in pairs(seat.deal_allwater_info) do
					local before_value = water_info.deal_water
					water_info.deal_water = water_info.deal_water * shoot_allplayer_times
					local shoot_allplayer_add = water_info.deal_water - before_value
					water_info.is_all_shoot = true
					local otherseat = tablelogic.get_seat_by_rid(table_data, otherrid)
					if otherseat ~= nil then
						local other_water_info = otherseat.deal_allwater_info[seat.rid]
						if other_water_info then
							other_water_info.deal_water = other_water_info.deal_water * shoot_allplayer_times
						end
					end
					local shoot_info_base = {
						shoot_player_rid 	= seat.rid,
						shoot_player_index 	= seat.index,
						shoot_player_win_water = shoot_allplayer_add,
						be_shoot_player_rid = water_info.seat_rid,
						be_shoot_player_index = water_info.seat_index,
						be_shoot_player_lose_water = - shoot_allplayer_add,
					}
					table.insert(table_data.shoot_allplayer_infos, shoot_info_base)
				end
			end
		end
	end
	filelog.sys_error("------tablelogic.check_player_shootall---------", table_data.shoot_allplayer_infos)
end

function tablelogic.check_all_waternum_equal()
	local server = tablelogic.server
	local table_data = server.table_data
	local all_deal_water = 0
	for index, seat in ipairs(table_data.seats) do
		if seat.rid ~= 0 and seat.state == SSSSeatState.SEAT_STATE_SORTCARDS_OVER then
			all_deal_water = all_deal_water + seat.deal_allwater
		end
	end
	if all_deal_water ~= 0 then
		filelog.sys_error("-----------deal_allwater---is not equal-------", all_deal_water)
	end
end

function tablelogic.balance(tableobj)
	local server = tablelogic.server
	local tablerobothelper = server:get_logicbyname("tablerobothelper")
	local higest_water = 0
	local higest_water_index = 0
	for index, seat in ipairs(tableobj.seats) do
		if seat.rid ~= 0 and seat.state == SSSSeatState.SEAT_STATE_SORTCARDS_OVER then
			if seat.deal_allwater > higest_water then
				higest_water = seat.deal_allwater
				higest_water_index = seat.index
			end
		end
	end
	if higest_water_index ~= 0 then
		tableobj.banker_seat_index = higest_water_index
	end
	local zhuangseat = tableobj.seats[tableobj.banker_seat_index]
	if not zhuangseat then return end
	local roomseatlogic = server:get_logicbyname("seatlogic")
	zhuangseat.balance_score = 0
	if zhuangseat.final_cards == nil or #zhuangseat.final_cards == 0 then
		zhuangseat.final_cards =  tabletool.deepcopy(zhuangseat.cards)
	end
	if tableobj.tablerecords.addinfos == nil then
		tableobj.tablerecords.addinfos = {}
	end
	local addinfos = tableobj.tablerecords.addinfos
	addinfos[zhuangseat.rid] = {}
	addinfos[zhuangseat.rid].banker_xiazhu_times = 1
	addinfos[zhuangseat.rid].xiazhu_times = 1
	---先记录庄家该获得多少钻石和友豆
	local balance_indexs = {}
	table.insert(balance_indexs, zhuangseat.index)
	for index, seat in ipairs(tableobj.seats) do
		if roomseatlogic.is_ingame(seat) then
			if seat.final_cards == nil or #seat.final_cards == 0 then
				seat.final_cards = tabletool.deepcopy(seat.cards)
			end
			if seat.index ~= tableobj.banker_seat_index then
				if seat.deal_allwater < 0 then
					if tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZUANSI or tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
						local dealnum = seat.deal_allwater * tableobj.conf.score_diamond
						seat.balance_score = 0
						seat.balance_score = seat.balance_score + dealnum
						zhuangseat.balance_score = zhuangseat.balance_score - dealnum
					end
				end
			end
		end
	end
	----第一次平账
	if tableobj.tablerecords.tmpdiamond == nil then
		tableobj.tablerecords.tmpdiamond = {}
	end
	local balance_pro_info = nil
	if tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZUANSI or tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
		balance_pro_info = tablelogic.balance_protect(tableobj.conf.table_type, balance_indexs)
	elseif tableobj.conf.table_type == SSSTableType.TABLE_TYPE_COIN then
		balance_pro_info = tablelogic.balance_protect(tableobj.conf.table_type, balance_indexs)
	end
	local zhuang_beginvalue = zhuangseat.diamond
	local zhuang_beginvalue_coin = zhuangseat.coin
	local first_balance = zhuangseat.balance_score
	if tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZUANSI or tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
		zhuangseat.diamond = zhuangseat.diamond + zhuangseat.balance_score
	elseif tableobj.conf.table_type == SSSTableType.TABLE_TYPE_COIN then
		zhuangseat.coin = zhuangseat.coin + zhuangseat.balance_score
	elseif tableobj.conf.table_type == SSSTableType.TABLE_TYPE_FANGKA then
		zhuangseat.score = zhuangseat.score + zhuangseat.balance_score
	end
	zhuangseat.balance_total = zhuangseat.balance_total + zhuangseat.balance_score
	balance_indexs = {}
	table.insert(balance_indexs, zhuangseat.index)
	zhuangseat.balance_score = 0
	for index, seat in ipairs(tableobj.seats) do
		if roomseatlogic.is_ingame(seat) then
			if seat.final_cards == nil or #seat.final_cards == 0 then
				seat.final_cards = tabletool.deepcopy(seat.cards)
			end
			if seat.index ~= tableobj.banker_seat_index then
				if seat.deal_allwater >= 0 then
					if tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZUANSI or tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
						local dealnum = seat.deal_allwater * tableobj.conf.score_diamond
						seat.balance_score = 0
						seat.balance_score = seat.balance_score + dealnum
						zhuangseat.balance_score = zhuangseat.balance_score - dealnum
					end
				end
			end
		end
	end
	--第二次平账
	if tableobj.tablerecords.tmpdiamond == nil then
		tableobj.tablerecords.tmpdiamond = {}
	end
	balance_pro_info = nil
	if tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZUANSI or tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
		balance_pro_info = tablelogic.balance_protect(tableobj.conf.table_type, balance_indexs)
	elseif tableobj.conf.table_type == SSSTableType.TABLE_TYPE_COIN then
		balance_pro_info = tablelogic.balance_protect(tableobj.conf.table_type, balance_indexs)
	end
	local data = {}
	local tmpdiamond = tableobj.tablerecords.tmpdiamond
	local getjackplayers = {}
	-----扣除输赢
	if tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZUANSI or tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
		for index, seat in ipairs(tableobj.seats) do
			if roomseatlogic.is_ingame(seat) and seat.state ~= SSSSeatState.SEAT_STATE_NO_PLAYER then
				if seat.index == tableobj.banker_seat_index then
					local bebanlance = zhuang_beginvalue
					if tmpdiamond[seat.rid] == nil then 
						tmpdiamond[seat.rid] = {} 
					end
					tmpdiamond[seat.rid].money_type = EMoneyType.DIAMOND
					tmpdiamond[seat.rid].rolename = seat.playerinfo.rolename
					tmpdiamond[seat.rid].value = seat.balance_score + first_balance
					tmpdiamond[seat.rid].beginvalue = bebanlance
					seat.diamond = seat.diamond + seat.balance_score
					seat.balance_total = seat.balance_total + seat.balance_score
					tmpdiamond[seat.rid].endvalue = seat.diamond
					seat.playerinfo.diamond = seat.playerinfo.diamond + seat.balance_score + first_balance
					data[seat.rid] = {
						beginvalue = bebanlance,
						value = seat.balance_score + first_balance,
						endvalue = 0,
						rolename = seat.playerinfo.rolename,
						real_change = 0,
						total_bet = 0,
						level = seat.playerinfo.level,
					}
					seat.balance_score = seat.balance_score + first_balance
					data[seat.rid].endvalue = seat.diamond
				else
					local bebanlance = seat.diamond
					if tmpdiamond[seat.rid] == nil then 
						tmpdiamond[seat.rid] = {} 
					end
					tmpdiamond[seat.rid].money_type = EMoneyType.DIAMOND
					tmpdiamond[seat.rid].rolename = seat.playerinfo.rolename
					tmpdiamond[seat.rid].value = seat.balance_score
					tmpdiamond[seat.rid].beginvalue = seat.diamond
					seat.diamond = seat.diamond + seat.balance_score
					seat.balance_total = seat.balance_total + seat.balance_score
					tmpdiamond[seat.rid].endvalue = seat.diamond
					seat.playerinfo.diamond = seat.playerinfo.diamond + seat.balance_score
					data[seat.rid] = {
						beginvalue = bebanlance,
						value = seat.balance_score,
						endvalue = 0,
						rolename = seat.playerinfo.rolename,
						real_change = 0,
						total_bet = 0,
						level = seat.playerinfo.level,
					}
					data[seat.rid].endvalue = seat.diamond
				end
			end
		end
		local comment = tablelogic.create_comment()
		write_table_log(comment, balance_pro_info)
		for key, player_data in pairs(data) do
			player_data.real_change = player_data.value
			if player_data.value > 0 then
				---filelog.sys_error("------player_data.value----", player_data.value, tableobj.conf.service_fee_rate)
				if tableobj.conf.is_get_service_fee == true then
					player_data.value = player_data.value - math.floor(2 * player_data.value * tableobj.conf.service_fee_rate)
				else
					player_data.value = player_data.value
				end
				local seat = tablelogic.get_seat_by_rid(tableobj, key)
				if seat then
					seat.diamond = player_data.beginvalue + player_data.value
					player_data.endvalue = player_data.beginvalue + player_data.value
					seat.playerinfo.diamond = player_data.beginvalue + player_data.value
					seat.balance_score = player_data.value
					-- if player_data.value >= DNSENDHORSEMAP.GET_MONEY_MIN and  seat.card_type >= DNCardType.CARD_TYPE_NIU_NINE then 
					-- 	tablelogic.send_horseracelamp(seat.playerinfo.rolename, seat.card_type, player_data.value / 100)
					-- end
				end
			end
			local playseat = tablelogic.get_seat_by_rid(tableobj, key)
			if playseat then
				---player_data.total_bet = tableobj.conf.score_diamond * playseat.xiazhu_times
				player_data.total_bet = tableobj.conf.score_diamond * playseat.deal_allwater
			end
		end
		---server:send_notice_to_gatenode("game_balance_diamond", data, comment)
		---filelog.sys_error("-------------game_balance_diamond--------", data)
		local status,comment = tablelogic.game_balance_diamond(data, comment)

		if not status then
			filelog.sys_error("---------balance_diamond_failed----------")
		else  
			local noticemsg = { }
    		noticemsg.money_change_list = { }
		    --扣费成功，修改数据
    		for rid,rv in pairs(data) do
        		local tmpseat = tablelogic.get_seat_by_rid(tableobj, rid)
        		tmpseat.playerinfo.diamond = tmpseat.playerinfo.diamond + rv.value
            	local item = { 
                	rid = rid,
                	money_type = EMoneyType.DIAMOND, --金钱类型：1金币 2钻石
            	}
            	item.final_value = rv.endvalue
            	item.change_value = rv.value
            	table.insert(noticemsg.money_change_list,item)
    		end
    		--通知客户端
    		if #(noticemsg.money_change_list) > 0 then
        		for _,seat in pairs(tableobj.seats) do
            		if not roomseatlogic.is_empty(seat) and not seat.is_robot then
                		server:send_notice_to_players({seat.rid}, "moneychangeN", noticemsg)
            		end
            	end
            end
        end
		tablerobothelper.balance_notice_robots(data, comment)
		if tableobj.conf.is_train_diamond == 1 then
			local trainlogic = server:get_logicbyname("trainlogic")
			trainlogic.balance_score()
		end
	elseif tableobj.conf.table_type == SSSTableType.TABLE_TYPE_COIN then
		local rid_values_list = {
			coin = {},
			diamond = {},
		}
		for index, seat in ipairs(tableobj.seats) do
			if roomseatlogic.is_ingame(seat) and seat.state ~= SSSSeatState.SEAT_STATE_NO_PLAYER then
				if seat.index == tableobj.banker_seat_index then
					local bebanlance = zhuang_beginvalue_coin
					local debanlance = seat.diamond
					if tmpdiamond[seat.rid] == nil then 
						tmpdiamond[seat.rid] = {} 
					end
					tmpdiamond[seat.rid].money_type = EMoneyType.COIN
					tmpdiamond[seat.rid].rolename = seat.playerinfo.rolename
					tmpdiamond[seat.rid].value = seat.balance_score + first_balance
					tmpdiamond[seat.rid].beginvalue = bebanlance
					seat.coin = seat.coin + seat.balance_score
					seat.balance_total = seat.balance_total + seat.balance_score
					tmpdiamond[seat.rid].endvalue = seat.coin
					seat.playerinfo.coin = seat.playerinfo.coin + seat.balance_score + first_balance
					rid_values_list.coin[seat.rid] = {
						beginvalue = bebanlance,
						value = seat.balance_score + first_balance,
						endvalue = 0,
						rolename = seat.playerinfo.rolename,
					}
					rid_values_list.coin[seat.rid].endvalue = seat.coin
					rid_values_list.diamond[seat.rid] = {
						beginvalue = debanlance,
						value = 0,
						endvalue = 0,
						rolename = seat.playerinfo.rolename,
					}
					seat.balance_score = seat.balance_score + first_balance
					rid_values_list.diamond[seat.rid].endvalue = seat.diamond
				else
					local bebanlance = seat.coin
					local debanlance = seat.diamond
					if tmpdiamond[seat.rid] == nil then 
						tmpdiamond[seat.rid] = {} 
					end
					tmpdiamond[seat.rid].money_type = EMoneyType.COIN
					tmpdiamond[seat.rid].rolename = seat.playerinfo.rolename
					tmpdiamond[seat.rid].value = seat.balance_score
					tmpdiamond[seat.rid].beginvalue = seat.coin
					seat.coin = seat.coin + seat.balance_score
					seat.balance_total = seat.balance_total + seat.balance_score
					tmpdiamond[seat.rid].endvalue = seat.coin
					seat.playerinfo.coin = seat.playerinfo.coin + seat.balance_score
					rid_values_list.coin[seat.rid] = {
						beginvalue = bebanlance,
						value = seat.balance_score,
						endvalue = 0,
						rolename = seat.playerinfo.rolename,
					}
					rid_values_list.coin[seat.rid].endvalue = seat.coin
					rid_values_list.diamond[seat.rid] = {
						beginvalue = debanlance,
						value = 0,
						endvalue = 0,
						rolename = seat.playerinfo.rolename,
					}
					rid_values_list.diamond[seat.rid].endvalue = seat.diamond
				end
			end
		end
		local comment = tablelogic.create_comment()
		write_table_log(comment, balance_pro_info)
		server:send_notice_to_gatenode("game_balance_coin_diamond", rid_values_list, comment)
		filelog.sys_error("---rid_values_list---", rid_values_list, tableobj.conf.uuid, tableobj.one_start_time)
	elseif tableobj.conf.table_type == SSSTableType.TABLE_TYPE_TRAIN then
		for index, seat in ipairs(tableobj.seats) do
			if roomseatlogic.is_ingame(seat) and seat.state ~= SSSSeatState.SEAT_STATE_NO_PLAYER then
				seat.train_score = seat.train_score + seat.balance_score
			end
		end
		local trainlogic = server:get_logicbyname("trainlogic")
		trainlogic.balance_score()
	elseif tableobj.conf.table_type == SSSTableType.TABLE_TYPE_FANGKA then
		if tableobj.gamerecords == nil then tableobj.gamerecords = {} end
		for index, seat in ipairs(tableobj.seats) do
			if roomseatlogic.is_ingame(seat) and seat.state ~= SSSSeatState.SEAT_STATE_NO_PLAYER then
				if seat.index == tableobj.banker_seat_index then
					seat.score = seat.score + seat.balance_score
					seat.balance_score = seat.balance_score + first_balance
				else
					seat.score = seat.score + seat.balance_score
				end
				seat.balance_total = seat.balance_total + seat.balance_score 
				if tableobj.gamerecords[seat.rid] == nil then 
					tableobj.gamerecords[seat.rid] = {
						rid = seat.rid,
						total_score = seat.score,
						win_num = 0,
						fail_num = 0,
						rolename = seat.playerinfo.rolename,
						logo = seat.playerinfo.logo
					}
				end
				tableobj.gamerecords[seat.rid].total_score = seat.score
				if seat.balance_score > 0 then
					tableobj.gamerecords[seat.rid].win_num = tableobj.gamerecords[seat.rid].win_num + 1
				elseif seat.balance_score < 0 then
					tableobj.gamerecords[seat.rid].fail_num = tableobj.gamerecords[seat.rid].fail_num + 1
				end
			end
		end
	end
end

function tablelogic.send_horseracelamp(rolename, card_type, get_num)
	local horseconf = configdao.get_common_conf("horselampconf")
	if not horseconf or not horseconf[1] then return end
	local formatname = string.format(DNLAMPCOLOR.GREEN, rolename)
	local formatnum = string.format(DNLAMPCOLOR.RED, tostring(get_num))
	local formatcard = string.format(DNLAMPCOLOR.GOLD, DNCardTypeName[card_type])
	local horsestring = string.format(horseconf[1], formatname, formatcard, formatnum)
	local msg = {
		content = horsestring,
	}
	local result = cluster.send("gatenode", ".router", "addpopmessage", msg.content)
end

function  tablelogic.create_comment()
    local table_data = tablelogic.server.table_data
    local tradeid = skynet.call(".nodeuuid", "lua", "getuuid")
    local ismatchtable = false
    if table_data.conf.match_type ~= nil and table_data.conf.match_type ~= 0 then
    	ismatchtable = true
    end
    return {
			table_uuid = table_data.conf.uuid,
			table_tradeid = tradeid, 
			start_time = table_data.one_start_time,
			replay_logname = table_data.replaylogname,
			is_matchtable = ismatchtable,
		}
end


function tablelogic.is_gameend(tableobj)
	if tableobj.state == SSSTableState.TABLE_STATE_ONE_GAME_END 
		or tableobj.state == SSSTableState.TABLE_STATE_WAIT_PLAYER_SITDOWN or tableobj.state == SSSTableState.TABLE_STATE_WAIT_ALL_READY
		or tableobj.state == SSSTableState.TABLE_STATE_ONE_GAME_END_AFTER or tableobj.state == SSSTableState.TABLE_STATE_GAME_START then
		return true
	end
	return false
end

--- 判断当前局是否已经结束游戏
function tablelogic.is_onegameend(tableobj)
	if tableobj.state == SSSTableState.TABLE_STATE_ONE_GAME_END then
		return true
	end
	if tableobj.state == SSSTableState.TABLE_STATE_ONE_GAME_END_AFTER then
		return true
	end
	return tablelogic.is_gameend(tableobj)
end

function tablelogic.standuptable(tableobj, msgbody, seat)
	local server = tablelogic.server
	if not tablelogic.is_onegameend(tableobj) and seat.state ~= SSSSeatState.SEAT_STATE_WAIT_NEXT_GAME then
		if tableobj.conf.table_type == SSSTableType.TABLE_TYPE_FANGKA and 
				(tableobj.state == SSSTableState.TABLE_STATE_START_GAME or tableobj.state == SSSTableState.TABLE_STATE_WAIT_START_GAME) then
		else
			seat.is_tuoguan = DNBOOL.TRUE
			return
		end
	end
	tableobj.sitdown_player_num = tableobj.sitdown_player_num - 1
	local noticemsg = {
		rid = seat.rid, 
		seat_index = seat.index,
		state = seat.state,
		reason = SSSEStandupReason.STANDUP_REASON_ONSTANDUP,
	}
	local rids = tablelogic.getallrids(tableobj)
	local cprids = {}
	for index, rid in ipairs(rids) do
		if rid ~= seat.rid then table.insert(cprids, rid) end
	end
	server:send_notice_to_players(cprids, "standuptableN", noticemsg, nil, nil)
	if seat.playerinfo.level == 99 then
		skynet.pcall(skynet.send, ".robotmgr", "lua", "leavetableN", seat.rid, skynet.self())
	end
	seat.state = SSSSeatState.SEAT_STATE_NO_PLAYER
	if tableobj.waits[seat.rid] == nil then
		local waitinfo = {
			playerinfo = {},
		}
		tableobj.waits[seat.rid] = waitinfo
		waitinfo.rid = seat.rid
		waitinfo.is_mirror = seat.is_mirror
		waitinfo.is_matching = seat.is_matching
		waitinfo.gatenode_id = seat.gatenode_id
		waitinfo.agent_address = seat.agent_address
		waitinfo.playerinfo.rolename = seat.playerinfo.rolename
		waitinfo.playerinfo.logo = seat.playerinfo.rolename
		waitinfo.playerinfo.sex = seat.playerinfo.sex
		waitinfo.playerinfo.ip_address = seat.playerinfo.ip_address
		waitinfo.playerinfo.intro = seat.playerinfo.intro
		waitinfo.playerinfo.downvoted_num = seat.playerinfo.downvoted_num
		waitinfo.playerinfo.upvoted_num = seat.playerinfo.upvoted_num
		waitinfo.playerinfo.gps_addr = seat.playerinfo.gps_addr
		waitinfo.playerinfo.logoframe = seat.playerinfo.logoframe
		tableobj.cur_watch_playernum = tableobj.cur_watch_playernum + 1
	end
	local seatlogic = server:get_logicbyname("seatlogic")
	seatlogic.clear_seat(seat)
end

function tablelogic.restart_matchtable(table_data, rid)
	local rids = {}
	local ts = timetool.get_time()
	for k, v in ipairs(table_data.seats) do
		if v.rid > 100 and v.rid ~= rid and v.playerinfo.level ~= 99 then
			if v.state ==  SSSSeatState.SEAT_STATE_WAIT_READY then
			elseif v.state == SSSSeatState.SEAT_STATE_WAIT_START then
				table.insert(rids, v.rid)
			end
		end
	end
	----踢掉进入匹配的玩家
	for index, re_rid in ipairs(rids) do
		for _, seat in ipairs(table_data.seats) do
			if re_rid ~= 0 and seat.rid ~= 0 and seat.rid == re_rid and seat.state ~= SSSSeatState.SEAT_STATE_NO_PLAYER then
				tablelogic.passive_standuptable(table_data, nil, seat, SSSEStandupReason.STANDUP_REASON_TABLE_MATCH)
			end
		end
	end
	for _, seat in ipairs(table_data.seats) do
		if seat.rid ~= 0 and seat.playerinfo.level == 99 then
			tablelogic.passive_standuptable(table_data, nil, seat, SSSEStandupReason.STANDUP_REASON_READYTIMEOUT_STANDUP)
		end
	end
	if #rids == 0 then
		if table_data.is_rematch == true then table_data.is_rematch = false end
	end
	if table_data.conf.table_type == SSSTableType.TABLE_TYPE_ZUANSI then
		skynet.send(".router","lua","restart_matchtable", rids, table_data.conf.match_type)
	elseif table_data.conf.table_type == SSSTableType.TABLE_TYPE_COIN then
		skynet.send(".router", "lua", "restart_cointable", rids, table_data.conf.match_type)
	end
end

function tablelogic.leavetable( tableobj, msgbody, seat, rid, reason)
	local server = tablelogic.server
	if tableobj.waits[rid] then tableobj.waits[rid] = nil end
	if tableobj.cur_watch_playernum > 0 then
		tableobj.cur_watch_playernum = tableobj.cur_watch_playernum - 1
	end
	if seat ~= nil and tableobj.conf.cur_player_num > 0 then
		if tableobj.conf.table_type == SSSTableType.TABLE_TYPE_TRAIN then
			if tablelogic.is_onegameend(tableobj) then tableobj.conf.cur_player_num = tableobj.conf.cur_player_num - 1 end
		else
			tableobj.conf.cur_player_num = tableobj.conf.cur_player_num - 1
		end
		server:updateplayernum()
	end
	--通知dnnode删除table
	if reason == nil then
		skynet.call(".router", "lua", "clear_ridinfo", 0, rid, tableobj.conf.table_index, tableobj.conf.table_type)
	else
		if reason ~= SSSEStandupReason.STANDUP_REASON_TABLE_CHUANZHUO then
			skynet.call(".router", "lua", "clear_ridinfo", 0, rid, tableobj.conf.table_index, tableobj.conf.table_type)
		end
	end
	local seatlogic = server:get_logicbyname("seatlogic")
	if seat ~= nil then
		if tableobj and tableobj.conf and tableobj.conf.table_type == SSSTableType.TABLE_TYPE_TRAIN then
			if not tablelogic.is_onegameend(tableobj) then
				seat.is_force_quit = 1
			else
				seatlogic.clear_seat(seat)
			end
		else
			seatlogic.clear_seat(seat)
		end
	end
	if not tableobj or not tableobj.conf then return end
	------如果是匹配场,把准备好的玩家放入匹配队列
	if tableobj.conf.match_type ~= 0 then
		----filelog.sys_error("------tableobj.conf.match_type----", tableobj.conf.match_type, tableobj.is_rematch, rid)
		if tableobj.is_rematch == false then
			local is_allready, ready_num, is_one_leave = tablelogic.check_all_ready(tableobj)
			---filelog.sys_error("-----tablelogic.leavetable-----", is_allready, ready_num, is_one_leave)
			if is_one_leave == true then
				if is_allready == true and ready_num == 1 then
					tableobj.is_rematch = true
					tablelogic.restart_matchtable(tableobj, rid) --匹配场，将座位上玩家，加入匹配队列
					tableobj.is_rematch = false
				end
			end
		end
	end
	if tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZUANSI or tableobj.conf.table_type == SSSTableType.TABLE_TYPE_COIN then
		local isempty = tablelogic.table_empty()
		if isempty == true and tableobj.is_deleting == false then
			tableobj.is_deleting = true
			if tableobj.delete_table_timer_id == -1 then
				local noticemsg = {
					table_index = tableobj.conf.table_index,
					reason = "tableempty",
				}
				tableobj.delete_table_timer_id = timer.settimer(1*100, "delete_table", noticemsg)
			end
		end
	elseif tableobj.conf.table_type == SSSTableType.TABLE_TYPE_TRAIN then
		if tablelogic.is_onegameend(tableobj) then
			local isempty = tablelogic.table_train_empty()
			if isempty == true and tableobj.is_deleting == false then
				tableobj.is_deleting = true
				if tableobj.delete_table_timer_id == -1 then
					local noticemsg = {
						table_index = tableobj.conf.table_index,
						reason = "tableempty",
					}
					tableobj.delete_table_timer_id = timer.settimer(1*100, "delete_table", noticemsg)
				end
			end
		end
	elseif tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
		local isempty = tablelogic.table_empty()
		if isempty == true and tableobj.is_deleting == false then
			tableobj.is_deleting = true
			if tableobj.delete_table_timer_id == -1 then
				local noticemsg = {
					table_index = tableobj.conf.table_index,
					reason = "tableempty",
				}
				tableobj.delete_table_timer_id = timer.settimer(tableobj.conf.retain_time*100, "delete_table", noticemsg)
			end
		end
	end
end

function tablelogic.table_empty()
	local server = tablelogic.server
	local table_data = server.table_data

	local empty = true
	for index, seat in ipairs(table_data.seats) do
		if seat.rid ~= 0 or seat.state ~= SSSSeatState.SEAT_STATE_NO_PLAYER then
			empty = false
			break
		end
	end
	return empty
end

function tablelogic.table_train_empty()
	local server = tablelogic.server
	local table_data = server.table_data

	local empty = true
	for index, seat in ipairs(table_data.seats) do
		if (seat.rid ~= 0 or seat.state ~= SSSSeatState.SEAT_STATE_NO_PLAYER) and seat.is_mirror == false then
			empty = false
			break
		end
	end
	return empty
end

function tablelogic.standupallplayer(tableobj, reason)
	for index, seat in ipairs(tableobj.seats) do
		tablelogic.passive_standuptable(tableobj, nil, seat, reason)
	end
end

function tablelogic.passive_standuptable(tableobj, msgbody, seat, reason)
	local server = tablelogic.server
	local table_data = tableobj
	tableobj.sitdown_player_num = tableobj.sitdown_player_num - 1
	local rids = tablelogic.getallrids(tableobj)
	local noticemsg = {
		rid = seat.rid, 
		seat_index = seat.index,
		state = seat.state,
		reason = reason,
	}
	local cprids = {}
	for index, rid in ipairs(rids) do
		if rid ~= seat.rid then table.insert(cprids, rid) end
	end
	server:send_notice_to_players(cprids, "standuptableN", noticemsg, nil, nil)
	local ntcnotice ={
		rid = seat.rid,
	}

	if reason == SSSEStandupReason.STANDUP_REASON_DELETE_TABLE or reason == SSSEStandupReason.STANDUP_REASON_DISCONNECTED 
		or reason == SSSEStandupReason.STANDUP_REASON_GM_DELETETABLE or reason == SSSEStandupReason.STANDUP_REASON_READYTIMEOUT_STANDUP 
		or reason == SSSEStandupReason.STANDUP_REASON_TABLE_END or reason == SSSEStandupReason.STANDUP_REASON_CLEAR_PLAYER_STATE 
		or reason == SSSEStandupReason.STANDUP_REASON_CANCELTABLE or reason == SSSEStandupReason.STANDUP_REASON_TABLE_CHUANZHUO 
		or reason == SSSEStandupReason.STANDUP_REASON_TABLE_MATCH then
		server:send_notice_to_players(rids, "leavetableN", ntcnotice, nil, nil)
	elseif reason == SSSEStandupReason.STANDUP_REASON_DISCONNECTED_NO_READY  then
	end
	if seat.playerinfo.level == 99 then
		skynet.pcall(skynet.send, ".robotmgr", "lua", "leavetableN", seat.rid, skynet.self())
	end
	seat.state = SSSSeatState.SEAT_STATE_NO_PLAYER
	if tableobj.waits and tableobj.waits[seat.rid] == nil then
		local waitinfo = {
			playerinfo = {},
		}
		tableobj.waits[seat.rid] = waitinfo
		waitinfo.rid = seat.rid
		waitinfo.is_mirror = seat.is_mirror
		waitinfo.gatenode_id = seat.gatenode_id
		waitinfo.agent_address = seat.agent_address
		waitinfo.playerinfo.rolename = seat.playerinfo.rolename
		waitinfo.playerinfo.logo = seat.playerinfo.rolename
		waitinfo.playerinfo.sex = seat.playerinfo.sex
		tableobj.cur_watch_playernum = tableobj.cur_watch_playernum + 1
	end
	
	if reason == SSSEStandupReason.STANDUP_REASON_DELETE_TABLE or reason == SSSEStandupReason.STANDUP_REASON_DISCONNECTED_NO_READY 
		or reason == SSSEStandupReason.STANDUP_REASON_READYTIMEOUT_STANDUP or reason == SSSEStandupReason.STANDUP_REASON_EMPTY_TABLE 
		or reason == SSSEStandupReason.STANDUP_REASON_DISCONNECTED or reason == SSSEStandupReason.STANDUP_REASON_TABLE_END 
		or reason == SSSEStandupReason.STANDUP_REASON_CLEAR_PLAYER_STATE or reason == SSSEStandupReason.STANDUP_REASON_TABLE_MATCH 
		or reason == SSSEStandupReason.STANDUP_REASON_CANCELTABLE or reason == SSSEStandupReason.STANDUP_REASON_TABLE_CHUANZHUO then
		tablelogic.leavetable(tableobj, msgbody, seat, seat.rid, reason)
	end
end

local function caclate_tip(base_cost, play_game_type, table_type)
	return 0
end

function tablelogic.get_tip()
	local server = tablelogic.server
	local table_data = server.table_data
	local tip = 0
	if table_data.conf.tip_percent == 0 then
		tip = caclate_tip(table_data.conf.score_diamond, table_data.conf.play_game_type, table_data.conf.table_type)
	else
		tip = math.floor(table_data.conf.score_diamond * table_data.conf.tip_percent)
	end
	return tip
end

function tablelogic.set_tip()
	local server = tablelogic.server
	local table_data = server.table_data
	local dnnodetipconf = getdnnodetipconf()
	if dnnodetipconf == nil then return end
	local tip_confs = dnnodetipconf[table_data.conf.table_type][table_data.conf.play_game_type]
	if tip_confs ~= nil and next(tip_confs) ~= nil then
		local tip_per = 0
		for index, tipobj in pairs(tip_confs) do
			if table_data.conf.score_diamond > tipobj.range[1] and table_data.conf.score_diamond <= tipobj.range[2] then
				tip_per = tipobj.per
			end
		end
		table_data.conf.tip_percent = tip_per
	end
end

function tablelogic.pay_tip(tableobj)
	local server = tablelogic.server
	local base_cost = tableobj.conf.score_diamond
	local roomseatlogic = server:get_logicbyname("seatlogic")
	local data = {}	
	local tip = 0
	if tableobj.conf.tip_percent == 0 then
		tip = caclate_tip(base_cost, tableobj.conf.play_game_type, tableobj.conf.table_type)
	else
		tip = math.floor(tableobj.conf.score_diamond * tableobj.conf.tip_percent)
	end
	if tableobj.tablerecords.tips == nil then
		tableobj.tablerecords.tips = {}
	end
	local comment = tablelogic.create_comment()
	for _, seat in ipairs(tableobj.seats) do
		if roomseatlogic.is_ingame(seat) and seat.state ~= SSSSeatState.SEAT_STATE_NO_PLAYER then
			if tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZUANSI or tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
				data[seat.rid] = {
					beginvalue = seat.diamond,
					value = tip,
					endvalue = 0,
				}
				seat.diamond = seat.diamond - tip
				if seat.diamond <= 0 then seat.diamond = 0 end
				seat.playerinfo.diamond = seat.playerinfo.diamond - tip
				data[seat.rid].endvalue = seat.diamond
				local tipsobj = { rid = seat.rid, tip = tip, money_type = EMoneyType.DIAMOND}
				table.insert(tableobj.tablerecords.tips, tipsobj)
			elseif tableobj.conf.table_type == SSSTableType.TABLE_TYPE_COIN then
				data[seat.rid] = {
					beginvalue = seat.coin,
					value = tip,
					endvalue = 0,
				}
				seat.coin = seat.coin - tip
				if seat.coin <= 0 then seat.coin = 0 end
				seat.playerinfo.coin = seat.playerinfo.coin - tip
				data[seat.rid].endvalue = seat.coin
				local tipsobj = { rid = seat.rid, tip = tip, money_type = EMoneyType.COIN}
				table.insert(tableobj.tablerecords.tips, tipsobj)
			end
		end
	end
	if tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZUANSI or tableobj.conf.table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
		server:send_notice_to_gatenode("game_sub_fuwufei", data, comment)
	elseif tableobj.conf.table_type == SSSTableType.TABLE_TYPE_COIN then
		---友豆场扣服务费
		server:send_notice_to_gatenode("game_sub_coin", data, comment)
	end
end

---扣除奖池抽水(取消奖池相关功能)
function tablelogic.pay_jackopt()
	-- local server = tablelogic.server
	-- local table_data = server.table_data
	-- if not tablelogic.is_in_jackpot() then return end
	-- local roomseatlogic = server:get_logicbyname("seatlogic")
	-- local base_cost = table_data.conf.score_diamond
	-- local jackoptconf = getjackoptconf()
	-- if not jackoptconf or not jackoptconf.chargeconf then return end
	-- local jackpoint = jackoptconf.chargeconf[table_data.conf.table_type][table_data.conf.play_game_type]
	-- local jacktip = math.floor( base_cost * jackpoint)
	-- if table_data.tablerecords.jacktips == nil then
	-- 	table_data.tablerecords.jacktips = {}
	-- end
	-- local data = {}
	-- local comment = tablelogic.create_comment()
	-- for _, seat in ipairs(table_data.seats) do
	-- 	if roomseatlogic.is_ingame(seat) and seat.state ~= SSSSeatState.SEAT_STATE_NO_PLAYER then
	-- 		----if tableobj.conf.table_type == SSSTableType.TABLE_TYPE_FANGKA then tip = 0 end
	-- 		if table_data.conf.table_type == SSSTableType.TABLE_TYPE_ZUANSI then
	-- 			data[seat.rid] = {
	-- 				beginvalue = seat.diamond,
	-- 				value = jacktip,
	-- 				endvalue = 0,
	-- 			}
	-- 			seat.diamond = seat.diamond - jacktip
	-- 			if seat.diamond <= 0 then seat.diamond = 0 end
	-- 			seat.playerinfo.diamond = seat.playerinfo.diamond - jacktip
	-- 			data[seat.rid].endvalue = seat.diamond
	-- 			local jacktipsobj = { rid = seat.rid, jacktip = jacktip, money_type = EMoneyType.DIAMOND, 
	-- 								beginvalue = data[seat.rid].beginvalue, 
	-- 								endvalue = data[seat.rid].endvalue
	-- 								}
	-- 			table.insert(table_data.tablerecords.jacktips, jacktipsobj)
	-- 		elseif table_data.conf.table_type == SSSTableType.TABLE_TYPE_COIN then
	-- 			data[seat.rid] = {
	-- 				beginvalue = seat.coin,
	-- 				value = jacktip,
	-- 				endvalue = 0,
	-- 			}
	-- 			seat.coin = seat.coin - jacktip
	-- 			if seat.coin <= 0 then seat.coin = 0 end
	-- 			seat.playerinfo.coin = seat.playerinfo.coin - jacktip
	-- 			data[seat.rid].endvalue = seat.coin
	-- 		end
	-- 	end
	-- end
	-- if table_data.conf.table_type == SSSTableType.TABLE_TYPE_ZUANSI then
	-- 	server:send_notice_to_gatenode("jackpot_sub_diamond", data, comment)
	-- elseif table_data.conf.table_type == SSSTableType.TABLE_TYPE_COIN then
	-- 	server:send_notice_to_gatenode("jackpot_sub_coin", data, comment)
	-- end
	-- ---更新奖池货币到总奖池
	-- local alljackoptmoney = tabletool.deepcopy(table_data.tablerecords.jacktips)
	-- skynet.send(".jackpotmgr", "lua", "updatejackoptnum", alljackoptmoney, comment)
end

----获得奖池信息到牌桌
function tablelogic.get_jackoptinfo()
	-- local server = tablelogic.server
	-- local table_data = server.table_data
	-- if table_data.jackopt_info == nil then table_data.jackopt_info = {} end
	-- table_data.jackopt_info.jackopt_num = 0
	-- table_data.jackopt_info.money_type = 0
	-- if not tablelogic.is_in_jackpot() then return end
	-- local result = skynet.call(".jackpotmgr", "lua", "getjackInfo", table_data.conf.score_diamond)
	-- if next(result) ~= nil then
	-- 	if result.jackopt_num and result.money_type then
	-- 		table_data.jackopt_info.jackopt_num = result.jackopt_num
	-- 		table_data.jackopt_info.money_type = result.money_type
	-- 	end
	-- end
end

function tablelogic.is_in_jackpot()
	local server = tablelogic.server
	local table_data = server.table_data
	local is_in_jackpot = false
	local jackoptconf = getjackoptconf()
	if not jackoptconf or not jackoptconf.childjackopt then return is_in_jackpot end
	for index, jackpotobj in pairs(jackoptconf.childjackopt) do
		if table_data.conf.score_diamond > jackpotobj.basescores[1] and table_data.conf.score_diamond <= jackpotobj.basescores[2] then
			is_in_jackpot = true
			break
		end
	end
	return is_in_jackpot
end

function tablelogic.get_movietime()
	local server = tablelogic.server
	local table_data = server.table_data
	--[[
		4.5 + 1 翻牌 打枪 2.5  特殊牌 1.5
		翻牌时间 （2*玩家数+ 1)*3 +打枪 2.5*打枪玩家数 + 全垒打 2 + 刷总分2

		(玩家数*1.5 + 1）*3 +（打枪玩家*4）+ 全垒打2 + 1.5
	--]]
	local seatlogic = server:get_logicbyname("seatlogic")
	local playernum = 0
	local shoot_num = 0
	local all_shoot_player = 0
	local movie_play_time = 0
	local special_card_num = 0
	---
	for index, seat in ipairs(table_data.seats) do
		if seat.rid ~= 0 and seatlogic.is_ingame(seat) then
			--movie_play_time = movie_play_time + 1.5
			playernum = playernum + 1
		end
	end
	--movie_play_time = movie_play_time + 1
	--movie_play_time = movie_play_time * 3
	

	for index, seat in ipairs(table_data.seats) do
		if seat.rid ~= 0 and seatlogic.is_ingame(seat) then
			if #seat.shoot_players_list > 0 then
				shoot_num = shoot_num + #seat.shoot_players_list
				if #seat.shoot_players_list + 1 == table_data.conf.max_player_num then
					all_shoot_player = all_shoot_player + 1
				end
			end
			if seat.special_card_type ~= 0 and seat.deal_as_special ~= 0 then
				special_card_num = special_card_num + 1
			end
		end
	end

	movie_play_time = movie_play_time + (playernum * 1.5 + 1) * 3 + shoot_num * 3 
	if all_shoot_player > 0 then
		movie_play_time = movie_play_time + 2
	end
	if special_card_num > 0 then
		movie_play_time = movie_play_time + 1.5
	end
	movie_play_time = movie_play_time + 1
	movie_play_time = movie_play_time * 100
	return movie_play_time
end

function tablelogic.clear(tableobj)
	if tableobj.timer_id > 0 then
		timer.cleartimer(tableobj.timer_id)
		tableobj.timer_id = -1
	end

	if tableobj.delete_table_timer_id > 0 then
		timer.cleartimer(tableobj.delete_table_timer_id)
		tableobj.delete_table_timer_id = -1
	end

	for _, seat in pairs(tableobj.seats) do
		if seat.ready_timer_id > 0 then
			timer.cleartimer(seat.ready_timer_id)
			seat.ready_timer_id = -1
		end
	end

	for k,v in pairs(tableobj) do
		tableobj[k] = nil
	end
end

function tablelogic.kill_all_waiter()
	local server = tablelogic.server
	local table_data = server.table_data
	if not table_data.waits or next(table_data.waits) == nil then return end

	for index, waitinfo in pairs(table_data.waits) do
		if table_data.cur_watch_playernum > 0 then
			table_data.cur_watch_playernum = table_data.cur_watch_playernum - 1
		end
		local seat = tablelogic.get_seat_by_rid(table_data, waitinfo.rid)
		if seat == nil then
			local ntcnotice = { rid = waitinfo.rid }
			server:send_notice_to_players({ waitinfo.rid } , "leavetableN", ntcnotice, nil, nil)
			skynet.call(".router", "lua", "clear_ridinfo", 0, waitinfo.rid, table_data.conf.table_index, table_data.conf.table_type)
		end
	end
	table_data.waits = {}
	-----清除
	-- for index, seat in ipairs(table_data.seats) do
	-- 	if seat.rid > 0 and seat.playerinfo and seat.playerinfo.level == 0 then
	-- 		local status, ridmap = skynet.pcall(skynet.call, ".router", "lua", "get_role_data", nil, seat.rid)
	-- 		if status == true and ridmap and next(ridmap) ~= nil then
	-- 			if not ridmap.table_index or ridmap.table_index ~= table_data.conf.table_index then
	-- 				tablelogic.passive_standuptable(table_data, nil, seat, SSSEStandupReason.STANDUP_REASON_TABLE_CHUANZHUO)
	-- 			end
	-- 		else
	-- 			tablelogic.passive_standuptable(table_data, nil, seat, SSSEStandupReason.STANDUP_REASON_TABLE_CHUANZHUO)
	-- 		end
	-- 	end
	-- end
end

function tablelogic.do_all_balance()
	-- body
	local server = tablelogic.server
	local table_data = server.table_data
	
	local rids = tablelogic.getallrids(table_data)
	local big_balancentc = {
        table_index = table_data.conf.table_index,
        create_rid = table_data.conf.create_user_rid,
        create_rolename = table_data.conf.create_user_rolename,
        retain_to_num = table_data.conf.retain_to_num,
        curr_to_num = table_data.curr_to_num,
        is_gameend = true,
        start_time = table_data.conf.create_time,
        end_time = timetool.get_time(),
        table_type = table_data.conf.table_type,
        playergamerecordlist = {},
    }
    tablelogic.copy_tablebalance(big_balancentc.playergamerecordlist)
    server:send_notice_to_players(rids, "tablebalanceN", big_balancentc, nil, nil)
end

function tablelogic.game_sub_fangka(rid_values)
	local comment = tablelogic.create_comment()
    local status,result = skynet.pcall(cluster.call,"gatenode", ".router", "game_sub_fangka", rid_values, comment) 
    if not status then
        filelog.sys_error("game_sub_fangka call failed!")
        return false
    end
    return result,comment
end

function tablelogic.game_balance_fangka(rid_values)
	local comment = tablelogic.create_comment()
    local status,result = skynet.pcall(cluster.call,"gatenode", ".router", "game_balance_fangka", rid_values, comment)
    if not status then
        filelog.sys_error("game_balance_fangka call failed!")
        return false
    end
    return result,comment
end

function tablelogic.do_fangka_save()
	local server = tablelogic.server
	local table_data = server.table_data
	if table_data.conf.table_type ~= SSSTableType.TABLE_TYPE_FANGKA then return end 
	if table_data.gamerecords == nil then return end
	local rid_values = {}
	for i,seat in pairs(table_data.seats) do
		if seat.rid ~= 0 and seat.state ~= SSSSeatState.SEAT_STATE_WAIT_NEXT_GAME then
        	rid_values[seat.rid] = {}
        	rid_values[seat.rid].rolename = seat.playerinfo.rolename
        	rid_values[seat.rid].beginvalue = 0
        	rid_values[seat.rid].value = seat.score
        	rid_values[seat.rid].endvalue = seat.score
        end
    end
    local status = tablelogic.game_balance_fangka(rid_values)
    if not status then
        filelog.sys_error("game balance fangka failed!")
    else
        filelog.sys_info("game balance fangka ok.")
    end
end

function tablelogic.init_deal_cards()
	local server = tablelogic.server
	local table_data = server.table_data
	if table_data.deal_cards_temp == nil or table_data.deal_cards_temp then table_data.deal_cards_temp = {} end

	local function gen_common(table_data, newcards)
		local roomseatlogic = server:get_logicbyname("seatlogic")
		local ingamenum = 0
		for index, seat in ipairs(table_data.seats) do
			if roomseatlogic.is_ingame(seat) then
				ingamenum = ingamenum + 1
				if table_data.deal_cards_temp[index] == nil then table_data.deal_cards_temp[index] = {} end
				for i = 1, 13 do
					if #table_data.deal_cards_temp[index] < 13 then 
						table.insert(table_data.deal_cards_temp[index], table.remove(newcards, 1)) 
					end
				end
			end
		end
	end

	local function gen_deal_cards(table_data, cardtool_isopen, is_get_special, get_special_num, cardspool)
		local server = tablelogic.server
		local newcards = cardtool.get_new_cards(table_data.conf.poker_num, table_data.conf.is_have_joker)
		local tempcards = tabletool.deepcopy(newcards)
		if cardtool_isopen == true and is_get_special == true then
			if get_special_num > 0 then
				local pool_num = #cardspool or 0
				if get_special_num <= pool_num then
					local get_indexs = {}
					local temp_indexs = {}
					for index, cards in ipairs(cardspool) do
						table.insert(temp_indexs, index)
					end
					for i = 1, get_special_num do
						local get_index = base.get_random(1, #temp_indexs)
						table.insert(get_indexs, table.remove(temp_indexs, get_index)) 
					end
					newcards = {}
					for index, temp_index in ipairs(get_indexs) do
						local poolcard = cardspool[temp_index]
						if poolcard then
							for index, card in ipairs(poolcard) do
								table.insert(newcards, card)
							end
						end
					end
					for index, card in ipairs(tempcards) do
						local is_has = false 
						for _, newcard in ipairs(newcards) do
							if card == newcard then
								is_has = true
								break
							end
						end
						if is_has == false then
							table.insert(newcards, card)
						end
					end
					gen_common(table_data, newcards)
				else
					gen_common(table_data, newcards)
				end
			else
				gen_common(table_data, newcards)
			end
		else
			gen_common(table_data, newcards)
		end
		return ingamenum, tempcards
	end

	local function check_deal_cards(table_data, cardtool_isopen, is_get_special, get_special_num, cardspool)
		local above_niu_num = 0
		local niu_num = 0
		local overcomes = {}
		local player_in_game, over_tempcards = gen_deal_cards(table_data, cardtool_isopen, is_get_special, get_special_num, cardspool)
		---filelog.sys_error("------player_in_game, over_tempcards------", player_in_game, over_tempcards)
		--filelog.sys_error("------table_data.deal_cards_temp-----", table_data.deal_cards_temp)
		table_data.cards_stack = tabletool.deepcopy(over_tempcards)
		return true
	end
	local count = 1
	local cardtool_isopen = handcardstool.isopen
	local is_get_special = handcardstool.is_get_special
	local cardspool = handcardstool.cardspool
	local get_special_num = handcardstool.get_special_num
	---filelog.sys_error("---------handcardstool------", handcardstool)
	while (count > 0) do
		local is_ok = check_deal_cards(table_data, cardtool_isopen, is_get_special, get_special_num, cardspool)
		if is_ok == true then 
			break 
		end
		count = count - 1
	end
end

function tablelogic.get_gamename()
	local server = tablelogic.server
	local table_data = server.table_data
	local gamename = "sss"
    if table_data.conf.table_type == SSSTableType.TABLE_TYPE_ZUANSI or table_data.conf.table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
        gamename = gamename .. "_diamond_".. table_data.conf.match_type
    end
    return gamename
end

function tablelogic.game_balance_diamond(data, comment)
	local server = tablelogic.server
 	local tableobj = server.table_data
 	local sumvalue = 0
 	local real_datas = {}
 	for rid, itemdata in pairs(data) do
 		sumvalue = sumvalue + itemdata.real_change
 		if real_datas[rid] == nil and itemdata.level ~= 99 then
 			real_datas[rid] = {
 				beginvalue = itemdata.beginvalue,
				value = itemdata.value,
				endvalue = itemdata.endvalue,
				rolename = itemdata.rolename,
				real_change = itemdata.real_change,
				total_bet = itemdata.total_bet,
				level = itemdata.level,
 			}
 		end		
 	end
 	if sumvalue ~= 0 then
 		filelog.sys_error("-----------sumvalue ~= 0-------------", data, comment)
 		return false
 	end
 	---local status, result = skynet.pcall(cluster.call, "gatenode", ".router", "game_balance_diamond", data, comment)
    local status, result = skynet.pcall(cluster.call, "gatenode", ".router", "brgame_balance_diamond", real_datas, comment)
    if not status then
        filelog.sys_error("game_balance_diamond call failed!")
        return false
    else
        --记录流水日志
        local total_bet = 0
        local total_water = 0
        local sys_change = 0
        local total_change = 0
        local robot_num = 0
        for rid,item in pairs(data) do
        	if item.level ~= 99 then
            	total_water = total_water + math.abs(item.real_change or 0)
                total_bet = total_bet + (item.total_bet or 0)
            	sys_change = sys_change + item.real_change
            	total_change = total_change + item.value
                --记录下注值
            	local bet_logstr = string.format("%d,%d,%d,%d,%d,%d,%d,%d,%d,%s,%s,%s", EDiamondChange.DOBET, rid, item.level, 
            	0, 0, 0, 0, 0, 0, comment.table_uuid, comment.start_time, comment.table_tradeid)
            	skynet.send(".diamondlog", "lua", "write", bet_logstr)
                --记录流水变化值
            	local chg_logstr = string.format("%d,%d,%d,%d,%d,%d,%d,%d,%d,%s,%s,%s", EDiamondChange.FUWUFEI, rid, item.level, item.real_change, 
            	item.beginvalue, item.endvalue, 0, 0, 0, comment.table_uuid, comment.start_time, comment.table_tradeid)
            	if item.real_change ~= 0 then
                	skynet.send(".diamondlog", "lua", "write_file_redis", chg_logstr, rid)
            	else
                	skynet.send(".diamondlog", "lua", "write", chg_logstr)
            	end
            else
            	robot_num = robot_num + 1
            	total_bet = total_bet + (item.total_bet or 0)
            	total_water = total_water + math.abs(item.real_change or 0)
        	end
        end
        if robot_num == 0 then
        	total_bet = 0
        end
        --记录系统的流水变化
        --filelog.sys_error("----------sys_change-------", sys_change)
        local logstr = string.format("%d,%d,%d,%d,%d,%d,%d,%d,%d,%s,%s,%s", EDiamondChange.FUWUFEI, 0, 0, -sys_change, 0, 0, 0, 0, 0,
        comment.table_uuid, comment.start_time, comment.table_tradeid)
        skynet.send(".diamondlog", "lua", "write", logstr)
        
        --更新收益值,库存值，扣除抽水
        local gamename =  tablelogic.get_gamename(tableobj)
        --filelog.sys_error("--------handle_balance_result-------", gamename, total_change, total_water, total_bet)
        if robot_num > 0 then
        	skynet.call(".slotmgr", "lua", "handle_balance_result", gamename, total_change, total_water, total_bet, comment)
        end
        skynet.pcall(skynet.call,".slotmgr", "lua", "update_system_water_profit", gamename, sys_change - total_change)
    end
    return result,comment
end

return tablelogic
